赞
踩
Oracle 官方文档 Condition Interface
How is await() different from wait() ?
wait()
与 notify()
需要搭配 synchronized
关键字使用, 示例如下// 线程 A 的代码
synchronized(obj_A)
{
while(!condition){
obj_A.wait();
}
// do something
}
// 线程 B 的代码
synchronized(obj_A)
{
if(!condition){
// do something ...
condition = true;
obj_A.notify();
}
}
wait()
, notify()
需要搭配 synchronized
关键字使用 Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations.
wait(), notify(), notifyAll()
分解到了不同的对象中, 搭配上任意一种 Lock 的使用, 使得一个对象可以拥有多个等待集这里有一个术语是 waitset
, 具体含义是
wait(), notify(), notifyAll()
方法的调用会对等待集中的线程进行移入或移除操作所以, await() 和 signall 的添加, 实际上是为我们提供了一种方便的基于同一个锁, 实现多个条件的 wait() 和 notify() 操作, 以一个有界缓冲区的生产消费操作为例(该例子实际上是 ArrayBlockingQueue
的简化版 , 感兴趣的读者可以直接阅读源码)
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}

class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
synchronized(lock)
{
while (count == items.length)
lock.wait();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
lock.notify();
}
}
public Object take() throws InterruptedException {
synchronized(lock){
while (count == 0)
lock.wait();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
lock.notify();
return x;
}
}
}

class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
synchronized (lock) {
synchronized (notFull) {
while (count == items.length)
notFull.wait();
}
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
synchronized (notEmpty) {
notEmpty.notify();
}
}
}
public Object take() throws InterruptedException {
synchronized (lock) {
synchronized (notEmpty)
{
while (count == 0)
notEmpty.wait();
}
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
synchronized (notFull)
{
notFull.notify();
}
return x;
}
}
}

await(), signal(),signalAll() 的功用和 wait(), notify(), notifyAll() 基本相同, 区别是, 基于 Condition 的 await(), signal(), signalAll() 使得我们可以在同一个锁的代码块内, 优雅地实现基于多个条件的线程间挂起与唤醒操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。