一、Synchronized解决
import java.util.concurrent.*; public class Test { public static void main(String[] args) throws Exception { ExecutorService pool = Executors.newFixedThreadPool(3); PrintTask task = new PrintTask(); pool.execute(() -> { try { task.printA(); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.execute(() -> { try { task.printB(); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.execute(() -> { try { task.printC(); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.shutdown(); } private static class PrintTask{ private volatile static Integer flag = 0; private synchronized void printA() throws InterruptedException { while (true){ if (flag == 0){ System.out.println(Thread.currentThread().getName() + "-----A"); Thread.sleep(500); flag = 1; notifyAll(); }else{ wait(); } } } private synchronized void printB() throws InterruptedException { while (true){ if (flag == 1){ System.out.println(Thread.currentThread().getName() + "-----B"); Thread.sleep(500); flag = 2; notifyAll(); }else{ wait(); } } } private synchronized void printC() throws InterruptedException { while (true){ if (flag == 2){ System.out.println(Thread.currentThread().getName() + "-----C"); Thread.sleep(500); flag = 0; notifyAll(); }else{ wait(); } } } } }
输出:
二、lock解决
import java.util.concurrent.*; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Test { public static void main(String[] args) throws Exception { ExecutorService pool = Executors.newFixedThreadPool(3); PrintTask task = new PrintTask(); pool.execute(() -> { try { task.printA(); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.execute(() -> { try { task.printB(); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.execute(() -> { try { task.printC(); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.shutdown(); } private static class PrintTask{ private volatile static Integer flag = 0; private Lock lock = new ReentrantLock(); private Condition conditionA = lock.newCondition(); private Condition conditionB = lock.newCondition(); private Condition conditionC = lock.newCondition(); private void printA() throws InterruptedException { try { lock.lock(); while (true) { if (flag == 0) { System.out.println(Thread.currentThread().getName() + "-----A"); Thread.sleep(500); flag = 1; conditionB.signal(); } else { conditionA.await(); } } } finally { lock.unlock(); } } private void printB() throws InterruptedException { try { lock.lock(); while (true) { if (flag == 1) { System.out.println(Thread.currentThread().getName() + "-----B"); Thread.sleep(500); flag = 2; conditionC.signal(); } else { conditionB.await(); } } } finally { lock.unlock(); } } private void printC() throws InterruptedException { try { lock.lock(); while (true) { if (flag == 2) { System.out.println(Thread.currentThread().getName() + "-----C"); Thread.sleep(500); flag = 0; conditionA.signal(); } else { conditionC.await(); } } } finally { lock.unlock(); } } } }
输出:
三、信号量解决
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class Test { public static void main(String[] args) throws Exception { ExecutorService pool = Executors.newFixedThreadPool(3); PrintTask task = new PrintTask(); pool.execute(() -> { try { task.printA(); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.execute(() -> { try { task.printB(); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.execute(() -> { try { task.printC(); } catch (InterruptedException e) { e.printStackTrace(); } }); pool.shutdown(); } private static class PrintTask{ private Semaphore semaphoreA = new Semaphore(1); private Semaphore semaphoreB = new Semaphore(0); private Semaphore semaphoreC = new Semaphore(0); private void printA() throws InterruptedException { while (true) { semaphoreA.acquire(); System.out.println(Thread.currentThread().getName() + "-----A"); Thread.sleep(500); semaphoreB.release(); } } private void printB() throws InterruptedException { while (true) { semaphoreB.acquire(); System.out.println(Thread.currentThread().getName() + "-----B"); Thread.sleep(500); semaphoreC.release(); } } private void printC() throws InterruptedException { while (true) { semaphoreC.acquire(); System.out.println(Thread.currentThread().getName() + "-----C"); Thread.sleep(500); semaphoreA.release(); } } } }
注意:多次调用release,或release(int),可以动态增加permits的个数,构造参数中的permits数量是初始值,不是最终的许可数量。
输出: