问题:
有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 ---------------------------------------