迅雷笔试题:
编写一个程序,开启 3 个线程,这 3 个线程的 ID 分别为 A,B,C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出结果必须按 ABC 的顺序显示;如:ABCABC.... 依次递推.
解决思路:每个线程运行时先检查他依赖的线程是否已完成工作,线程 B 依赖线程 A 的完成,线程 C 依赖线程 B 和线程 A 的完成,线程 A 依赖线程 C 的完成.如果当前线程依赖的线程没有执行完,则阻塞当前线程直到条件满足再执行.
Condition.await() 会使当前线程暂时阻塞,并释放 ReentrantLock 锁.
Condition.signalAll() 会通知激活 Condition.await() 而阻塞的线程,这时被激活的线程就会继续检查(通过 while 循环))是否满足条件,如果满足而且再次获得 ReentrantLock 锁就能继续运行,否则继续等待.
1 import java.util.concurrent.locks.Condition;
2 import java.util.concurrent.locks.ReentrantLock;
3 4 public class ThreadDemo implements Runnable {
5 6 private ReentrantLock lock = new ReentrantLock();
7 private Condition condition = lock.newCondition();
8 //标记线程A的状态,true为刚执行完.为什么要两个变量?因为只使用一个变量,当线程A执行完后,a为true,B线程就会不停执行
9 //所以线程B执行要执行必须满足a==true&&a2==true
10 private volatile Boolean a = false,
a2 = false;
11 //标记线程B的状态,true为刚执行完.
12 private volatile Boolean b = false;
13 //标记线程C的状态,true为刚执行完.
14 private volatile Boolean c = true;
15 16@Override 17 public void run() {
18 String name = Thread.currentThread().getName();
19 lock.lock();
20 //进入临界区
21
try {
22
for (int i = 0; i < 10; i++) {
23
if (name.equals("B")) {
24 //只有a和a2同时为true时才打印B,否则阻塞当前线程
25
while (!a || !a2) {
26 condition.await(); //条件不满足,暂时阻塞线程,暂时释放lock
27
}
28 b = true;
29 a2 = false;
30
} else if (name.equals("C")) {
31
while (!a || !b) {
32 condition.await();
33
}
34 c = true;
35 b = false;
36
} else if (name.equals("A")) {
37
while (!c) {
38 condition.await();
39
}
40 a = true;
41 a2 = true;
42 b = false;
43 c = false;
44
}
45 System.out.print(name);
46 condition.signalAll(); //通知正在等待的线程,此时有可能已经满足条件
47
}
48
} catch(InterruptedException e) {
49 e.printStackTrace();
50
} finally {
51 lock.unlock(); // 记得要释放锁
52
}
53
}
54 55 public static void main(String[] args) throws InterruptedException {
56 ThreadDemo task = new ThreadDemo();
57 Thread thread1 = new Thread(task);
58 Thread thread2 = new Thread(task);
59 Thread thread3 = new Thread(task);
60 thread1.setName("A");
61 thread2.setName("B");
62 thread3.setName("C");
63 thread1.start();
64 thread2.start();
65 thread3.start();
66
}
67 68
}
来源: http://www.cnblogs.com/JT-L/p/5771455.html