java在可重入锁中等待条件
以下代码取自JavaDoc of ^{
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();
}
}
}
想象两个线程,消费者和生产者,一个使用take
,一个put
在BoundedBuffer
的单个实例上
让我们假设消费者首先运行take()
,他在其中锁定lock
,现在在notEmpty.await();
上循环
现在生产者如何通过锁定lock
进入put()
方法,而lock
已经由消费者持有
我错过了什么?当线程等待某个条件时,lock
是否“临时释放”?锁的重入到底意味着什么
# 1 楼答案
我使用单监视器测试了以下代码,以下代码的性能总是更好——在2核机器上测试,条件性能平均低于10-15%
# 2 楼答案
Lock
和synchronized
都允许一个线程在等待时放弃锁,而另一个线程可以获得锁。要停止等待,线程必须重新获取锁注意:它们不会完全释放,如果进行堆栈跟踪,可能会有多个线程同时持有锁,但最多有一个线程正在运行(其余线程将被阻塞)
从Condition.await()
# 3 楼答案
就重入性而言,这意味着持有某个锁的线程可以再次获取同一个锁。如果不是这样,一个
synchronized
方法将无法调用同一对象的另一个synchronized
方法重新进入并不意味着理解你的问题