问:说说 Condition 与传统线程协作的区别?
答:Condition
可以说是传统 Object.wait()
和 Object.natify()
的加强版,能够更加精细的控制多线程的休眠与唤醒。对于同一个锁我们可以创建多个 Condition
(即多个监视器),从而在不同的情况下使用不同的 Condition
。
举个例子,假设我们要实现多线程读写同一个缓冲区,当向缓冲区中写入数据之后唤醒读线程,当从缓冲区读出数据之后唤醒写线程。如果使用传统 Object.wait()/Object.notify()/Object.notifyAll()
实现该缓冲区,当向缓冲区写入数据后唤醒读线程时是没法通过 Object.notify()/Object.notifyAll()
明确的指定唤醒读线程,而只能通过 Object.notifyAll()
唤醒所有线程。但是通过 Condition
就可以明确的指定唤醒读线程。
下面的程序就演示了 Condition 特有的能力,我们模拟日常上班,每个启动线程都是一个岗位,上班以后 boss 发布一个 plain,然后 manager 赶紧顶上去接锅,然后 manager 把 boss 的 plain 发给 teamLeader,teamLeader 又把 plain 发给 coder,如下就是这么一种流程:
public class Test {
public static void main(String[] args) throws InterruptedException {
final OfficeWork work = new OfficeWork();
new Thread() {
public void run() {
work.coderCmd();
}
}.start();
new Thread() {
public void run() {
work.teamLeaderCmd();
}
}.start();
new Thread() {
public void run() {
work.managerCmd();
}
}.start();
Thread.sleep(2000);
work.bossCmd();
}
static class OfficeWork {
private Lock lock = new ReentrantLock();
private Condition cond1 = lock.newCondition();
private Condition cond2 = lock.newCondition();
private Condition cond3 = lock.newCondition();
public void bossCmd() {
try {
lock.lock();
cond1.signal();
System.out.println("Boss have a plain!");
} finally {
lock.unlock();
}
}
public void managerCmd() {
try {
lock.lock();
cond1.await();
Thread.sleep(500);
System.out.println("Manager received Cmd!");
} catch (Exception e) {
e.printStackTrace();
} finally {
cond3.signal();
lock.unlock();
}
}
public void coderCmd() {
try {
lock.lock();
cond2.await();
Thread.sleep(500);
System.out.println("Coder received Cmd!");
} catch (Exception e) {
e.printStackTrace();
} finally {
cond1.signal();
lock.unlock();
}
}
public void teamLeaderCmd() {
try {
lock.lock();
cond3.await();
Thread.sleep(500);
System.out.println("TeamLeader received Cmd!");
} catch (Exception e) {
e.printStackTrace();
} finally {
cond2.signal();
lock.unlock();
}
}
}
}
上面程序的运行结果一定如下:
Boss have a plain!
Manager received Cmd!
TeamLeader received Cmd!
Coder received Cmd!
本文参考自 Condition 与传统多线程协作区别问题解析