Condition
- Condition接口描述了可能会与锁有关联的条件变量。这些变量在用法与使用Object.wait访问的隐式监视器类似,但提供了更强大的功能。需要特别指出的是,单个Lock可能与多个Condition对象关联。为了避免兼容性问题,Condition方法的名称与对应的Object版本中的不同;
- 在Condition对象中,与wait、notify和notifyAll方法对应的分别是await、signal和signalAll;
- Condition实例实质上被绑定到一个锁上。要为特定Lock实例获得Condition实例,请使用器newCondition()方法。
面试题
1 package com.ccfdod.juc;
2
3 import java.util.concurrent.locks.Condition;
4 import java.util.concurrent.locks.Lock;
5 import java.util.concurrent.locks.ReentrantLock;
6
7 /**
8 * 题目:编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。
9 * 如:ABCABCABC……
10 */
11 class AlternateDemo {
12 //标志当前由哪一个线程输出,1代表A,2代表B,3代表C
13 private int number = 1;
14
15 Lock lock = new ReentrantLock();
16
17 //Condition的强大之处在于它可以为多个线程间建立不同的Condition
18 Condition condition1 = lock.newCondition();
19 Condition condition2 = lock.newCondition();
20 Condition condition3 = lock.newCondition();
21
22 // loopNum:当前循环轮数
23 public void loopA(int loopNum) {
24 //上锁
25 lock.lock();
26 try {
27 while (number != 1) {
28 //等待
29 condition1.await();
30 }
31
32 System.out.println(Thread.currentThread().getName() + ", currentLoopNum is " + loopNum);
33 number = 2;
34 //唤醒
35 condition2.signal();
36
37 } catch (InterruptedException e) {
38 e.printStackTrace();
39 } finally {
40 //确保释放锁
41 lock.unlock();
42 }
43 }
44
45 public void loopB(int loopNum) {
46 lock.lock();
47 try {
48 while (number != 2) {
49 condition2.await();
50 }
51
52 System.out.println(Thread.currentThread().getName() + ", currentLoopNum is " + loopNum);
53 number = 3;
54 condition3.signal();
55
56 } catch (InterruptedException e) {
57 e.printStackTrace();
58 } finally {
59 lock.unlock();
60 }
61 }
62
63 public void loopC(int loopNum) {
64 lock.lock();
65 try {
66 while (number != 3) {
67 condition3.await();
68 }
69
70 System.out.println(Thread.currentThread().getName() + ", currentLoopNum is " + loopNum);
71 number = 1;
72 condition1.signal();
73
74 } catch (InterruptedException e) {
75 e.printStackTrace();
76 } finally {
77 lock.unlock();
78 }
79 }
80 }
81
82 public class TestABCAlternate {
83
84 public static void main(String[] args) {
85 AlternateDemo ad = new AlternateDemo();
86
87 new Thread(new Runnable() {
88
89 @Override
90 public void run() {
91 for (int i = 0; i < 10; i++)
92 ad.loopA(i);
93 }
94 }, "A").start();
95
96 new Thread(new Runnable() {
97
98 @Override
99 public void run() {
100 for (int i = 0; i < 10; i++)
101 ad.loopB(i);
102 }
103 }, "B").start();
104
105 new Thread(new Runnable() {
106
107 @Override
108 public void run() {
109 for (int i = 0; i < 10; i++)
110 ad.loopC(i);
111 }
112 }, "C").start();
113 }
114 }