问题:
有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-1 B-1-1 C-1-1 --------------------------------------- A-2-1 B-2-1 C-2-1 --------------------------------------- A-3-1 B-3-1 C-3-1 --------------------------------------- A-4-1 B-4-1 C-4-1 --------------------------------------- A-5-1 B-5-1 C-5-1 --------------------------------------- A-6-1 B-6-1 C-6-1 --------------------------------------- A-7-1 B-7-1 C-7-1 --------------------------------------- A-8-1 B-8-1 C-8-1 --------------------------------------- A-9-1 B-9-1 C-9-1 ---------------------------------------
更多实现方案:
请参考《Java:现有线程T1/T2/T3,如何确保T1执行完成之后执行T2,T3在T2执行完成之后执行。》