這世上有三樣東西是別人搶不走的:一是吃進胃裏的食物,二是藏在心中的夢想,三是讀進大腦的書java
import java.util.concurrent.Semaphore; /** * @ClassName AlternatePrinting * @Author yunlogn * @Date 2019/5/21 * @Description 交替打印奇偶數 */ public class AlternatePrinting { static int i = 0; public static void main(String[] args) throws InterruptedException { Semaphore semaphoreOdd = new Semaphore(1); Semaphore semaphoreEven = new Semaphore(1); semaphoreOdd.acquire(); //讓奇數先等待啓動,因此先減掉偶數的信號量 等奇數線程來釋放 SemaphorePrintEven semaphorePrintEven = new SemaphorePrintEven(semaphoreOdd, semaphoreEven); Thread t1 = new Thread(semaphorePrintEven); t1.start(); SemaphorePrintOdd semaphorePrintOdd = new SemaphorePrintOdd(semaphoreOdd, semaphoreEven); Thread t2 = new Thread(semaphorePrintOdd); t2.start(); } /** * 使用信號量實現 */ static class SemaphorePrintOdd implements Runnable { private Semaphore semaphoreOdd; private Semaphore semaphoreEven; public SemaphorePrintOdd(Semaphore semaphoreOdd, Semaphore semaphoreEven) { this.semaphoreOdd = semaphoreOdd; this.semaphoreEven = semaphoreEven; } @Override public void run() { try { semaphoreOdd.acquire();//獲取信號量 semaphoreOdd在初始化的時候被獲取了信號量因此這裏被阻塞了,因此會先執行下面的奇數線程 while (true) { i++; if (i % 2 == 0) { System.out.println("偶數線程:" + i); semaphoreEven.release();//釋放偶數信號量 讓奇數線程那邊的阻塞解除 //再次申請獲取偶數信號量,由於以前已經獲取過,若是沒有奇數線程去釋放,那麼就會一直阻塞在這,等待奇數線程釋放 semaphoreOdd.acquire(); } } } catch (InterruptedException e) { e.printStackTrace(); } } } static class SemaphorePrintEven implements Runnable { private Semaphore semaphoreOdd; private Semaphore semaphoreEven; public SemaphorePrintEven(Semaphore semaphoreOdd, Semaphore semaphoreEven) { this.semaphoreOdd = semaphoreOdd; this.semaphoreEven = semaphoreEven; } @Override public void run() { try { semaphoreEven.acquire(); while (true) { i++; if (i % 2 == 1) { System.out.println("奇數線程:" + i); semaphoreOdd.release(); //釋放奇數信號量 讓偶數線程那邊的阻塞解除 //這裏阻塞,等待偶數線程釋放信號量 //再次申請獲取奇數信號量,須要等偶數線程執行完而後釋放該信號量,否則阻塞 semaphoreEven.acquire(); } } } catch (Exception ex) {} } } }
finally
來包裹釋放鎖資源import java.util.concurrent.atomic.AtomicInteger; /** * @ClassName AlternatePrinting * @Author yunlogn * @Date 2019/5/21 * @Description 交替打印奇偶數 */ public class AlternatePrinting { public static AtomicInteger atomicInteger = new AtomicInteger(1); public static void main(String[] args) throws InterruptedException { Thread a=new Thread(new AThread()); Thread b=new Thread(new BThread()); a.start(); b.start(); } public static class AThread implements Runnable { @Override public void run() { while (true) { synchronized (atomicInteger) { if (atomicInteger.intValue() % 2 != 0) { System.out.println("奇數線程:" + atomicInteger.intValue()); atomicInteger.getAndIncrement(); // 奇數線程釋放鎖資源 atomicInteger.notify(); try { atomicInteger.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { try { // 奇數線程等待 atomicInteger.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } public static class BThread implements Runnable { @Override public void run() { while (true){ synchronized (atomicInteger){ if(atomicInteger.intValue() %2== 0 ){ System.out.println("偶數線程:"+ atomicInteger.intValue()); atomicInteger.getAndIncrement(); // 偶數線程釋放鎖資源 atomicInteger.notify(); try { atomicInteger.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }else{ try { // 偶數線程等待 atomicInteger.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } }
public class TheadTest { public static void main(String[] args) { PrintDigitThread print1 = new PrintDigitThread((i) -> i % 2 == 1, "thread1"); PrintDigitThread print2 = new PrintDigitThread((i) -> i % 2 == 0, "thread2"); print1.start(); print2.start(); } } class ShareData { public static final AtomicInteger atomicInt = new AtomicInteger(0); } class PrintDigitThread extends Thread { private Predicate<Integer> predicate; public PrintDigitThread(Predicate<Integer> predicate, String name) { this.predicate = predicate; this.setName(name); } @Override public void run() { int v = ShareData.atomicInt.get(); while (v < 100) { synchronized (ShareData.atomicInt) { v = ShareData.atomicInt.get(); if (predicate.test(v)) { System.out.println(Thread.currentThread().getName() + ":" + v); ShareData.atomicInt.incrementAndGet(); try { ShareData.atomicInt.notify(); } catch (Exception ex) { } } else { try { ShareData.atomicInt.wait(); } catch (Exception ex) { } } } } } }
歡迎關注 http://yunlongn.github.iogit