1. 概括
- Condition是java条件队列的实现,这就意味着Condition的强大之处在于它可以为多个线程间建立不同的Condition。
- 作为一个多线程间协调通信的工具类,每个条件Contition对象内部维护了一个属于自己的等待队列,它使得某个或者某些线程一起等待某个条件(Condition ,只有当该条件具备( signal 或者 signalAll方法被带调用)时,这些等待线程才会被唤醒,从而重新争夺锁。
2. 实例
- 以下是来自《并发编程实战》一书的例子,第一段代码是原始的synchronized+notify+条件谓词实现的条件队列,第二段代码使用java并发包的Condition + Lock。
public class BoundedBuffer extends BaseBoundedBuffer<V>{
public BoundedBuffer(int size){super(size)};
public synchronized void put(V v) throws InterruptedException{
while(isFull()){
wait();
}
doPut(v);
notifyAll();
}
public synchronized V take(V v) throws InterruptedException{
while(isEmpty()){
wait();
}
V v = doTake();
notifyAll();
return v;
}
}
public class BoundedBuffer<V> extends BaseBoundedBuffer<V>{
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
public void put(V v) throws InterruptedException {
lock.lock();
try {
while (isFull())
notFull.await();
doPut(v);
notEmpty.signal();
} finally {
lock.unlock();
}
}
public V take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
V v = doTake();
notFull.signal();
return v;
} finally {
lock.unlock();
}
}
}
- 对比两端代码,它们实现的功能其实是一样的,第二段代码结构更加清晰。
3. 总结
- Condition 将 Object 监视器方法(wait、notify 和 notifyAll)根据条件的不同分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。与synchronized和Lock相比,Condition十分灵活,某些场景效率更高,适合多条件的讨论。