题目
两个线程轮流打印 1 - 100,必须使用 ReentrantLock 实现
思路
使用 condition 和 reentrantlock 即可配合实现有序,一个线程中调用 condition.await,该线程就会加入该 condition 对应的等待队列,再从另一个线程唤醒 condition 的线程,就可以让线程相互协作
class T1 extends Thread {
Lock lock;
Condition c1;
Condition c2;
private AtomicInteger count;
public T1(Lock lock, Condition c1, Condition c2, AtomicInteger count) {
this.lock = lock;
this.c1 = c1;
this.c2 = c2;
this.count = count;
}
public void run() {
lock.lock();
try {
T2.working(count, c2, c1);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class T2 extends Thread {
private Lock lock;
private Condition c1;
private Condition c2;
private AtomicInteger count;
public T2(Lock lock, Condition c1, Condition c2, AtomicInteger count) {
this.lock = lock;
this.c1 = c1;
this.c2 = c2;
this.count = count;
}
public void run() {
lock.lock();
try {
working(count, c1, c2);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (count.get() == 101) {
c1.signal(); //保证先把自己锁的线程一定能结束
}
lock.unlock();
}
}
public static void working(AtomicInteger count, Condition c1, Condition c2) throws InterruptedException {
while (count.get() <= 100) {
System.out.println(count);
count.incrementAndGet();
c1.signal();
c2.await();
}
}
}
class Main {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition c1 = lock.newCondition();
Condition c2 = lock.newCondition();
AtomicInteger count = new AtomicInteger(0);
T1 t1 = new T1(lock, c1, c2, count);
T2 t2 = new T2(lock, c1, c2, count);
t1.start();
t2.start();
}
}
总结
如果 T2 的 finally 没有对 if 的判断,会发现线程会卡住,思考一下原因:
- 100 的时候,T1 signal T2,T1 await 本身
- 101 的时候,T2 无法进入 while,那么 T2 解锁后结束,此时发现 T1 还卡住呢
所以,得加上判断最后让 T1 也解锁

京公网安备 11010502036488号