问题:
有a、b、c三个线程,使得它们按照abc依次执行10次。
实现:
package com.dx.juc.test;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ABC { public static void main(String[] args) { final AlternateDemo alternateDemo=new AlternateDemo(); new Thread(new Runnable() { public void run() { for(int i=1;i<10;i++){ alternateDemo.loopA(i); } } }, "A").start(); new Thread(new Runnable() { public void run() { for(int i=1;i<10;i++){ alternateDemo.loopB(i); } } }, "B").start(); new Thread(new Runnable() { public void run() { for(int i=1;i<10;i++){ alternateDemo.loopC(i); System.out.println("---------------------------------------"); } } }, "C").start(); }}class AlternateDemo { private Lock lock = new ReentrantLock(); private Condition conditionA = lock.newCondition(); private Condition conditionB = lock.newCondition(); private Condition conditionC = lock.newCondition(); // 一个标号,标记当前可以执行的线程编号.1-a线程可以执行,2-b线程可以执行,3-c线程可以执行。 private int flag = 1; public void loopA(int loopNum) { lock.lock(); try { // 1)等待喚醒 // 如果flag标记值不是1的话,就让线程处于等待状态,直到其他线程唤醒它。 if (flag != 1) { conditionA.await(); } // 2)被喚醒后,開始執行。 for (int i = 1; i <= 1; i++) { System.out.println(Thread.currentThread().getName() + "-" + loopNum + "-" + i); } // 3)修改標記flag,并喚醒下一個線程。 flag = 2; conditionB.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void loopB(int loopNum) { lock.lock(); try { // 1)等待喚醒 // 如果flag标记值不是2的话,就让线程处于等待状态,直到其他线程唤醒它。 if (flag != 2) { conditionB.await(); } // 2)被喚醒后,開始執行。 for (int i = 1; i <= 1; i++) { System.out.println(Thread.currentThread().getName() + "-" + loopNum + "-" + i); } // 3)修改標記flag,并喚醒下一個線程。 flag = 3; conditionC.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void loopC(int loopNum) { lock.lock(); try { // 1)等待喚醒 // 如果flag标记值不是3的话,就让线程处于等待状态,直到其他线程唤醒它。 if (flag != 3) { conditionC.await(); } // 2)被喚醒后,開始執行。 for (int i = 1; i <= 1; i++) { System.out.println(Thread.currentThread().getName() + "-" + loopNum + "-" + i); } // 3)修改標記flag,并喚醒下一個線程。 flag = 1; conditionA.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }}
测试打印结果:
A-1-1B-1-1C-1-1---------------------------------------A-2-1B-2-1C-2-1---------------------------------------A-3-1B-3-1C-3-1---------------------------------------A-4-1B-4-1C-4-1---------------------------------------A-5-1B-5-1C-5-1---------------------------------------A-6-1B-6-1C-6-1---------------------------------------A-7-1B-7-1C-7-1---------------------------------------A-8-1B-8-1C-8-1---------------------------------------A-9-1B-9-1C-9-1---------------------------------------
更多实现方案:
请参考《》