问题引入

用三个线程分别打印三次A, B, C, 要求保证其打印的顺序, 即打印出ABCABCABC

没错又是一道面试题, 后来学习了一些线程知识, 就突然想到这道题

解决方案

ReentrantLock绑定多个Condition来实现线程协作

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public class ABC {
static Lock lock = new ReentrantLock();
static Condition ca = lock.newCondition();
static Condition cb = lock.newCondition();
static Condition cc = lock.newCondition();

public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();

ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(a);
executor.execute(b);
executor.execute(c);

lock.lock();
try {
ca.signal();
} finally {
lock.unlock();
}

executor.shutdown();
}

static class A implements Runnable {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
lock.lock();
try {
ca.await();
System.out.print("A");
cb.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}

static class B implements Runnable {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
lock.lock();
try {
cb.await();
System.out.print("B");
cc.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}

static class C implements Runnable {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
lock.lock();
try {
cc.await();
System.out.print("C");
ca.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}

试着运行了一下, 完美解决

新问题

本以为完美解决了, 整个人沉浸在获得新知识的愉悦中, 情不自禁的多运行了几次

结果发现并不是每次都能完美运行, 偶尔会出现死锁…

随着学习的深入, 以后再来解决这个问题

如有大佬随手指点迷津, 愚不胜感激 :)