以下代码取自 JavaDoc of Condition
:
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();
}
}
}
想象 2 个线程,Consumer 和 Producer,一个使用 take
,一个 put
在单个实例上有界缓冲区
。
假设 Consumer 首先运行,运行 take()
,他在其中锁定 lock
,现在在 notEmpty.await 上循环();
。
现在 Producer 怎么可能进入 put()
方法而不是锁定 已经持有的 lock
消费者?
我在这里缺少什么? lock
在线程等待其条件之一时是否“临时释放”?那么锁的reentrancy到底是什么意思?
最佳答案
Lock
和synchronized
都允许一个线程在等待时放弃锁,而另一个线程可以获得锁。要停止等待,线程必须重新获取锁。
注意:它们不会完全释放它,如果您进行堆栈跟踪,您可能有多个线程似乎同时持有锁,但最多其中一个会运行(其余的将阻塞)
The lock associated with this Condition is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:
- Some other thread invokes the signal() method for this Condition and the current thread happens to be chosen as the thread to be awakened; or
- Some other thread invokes the signalAll() method for this Condition; or
- Some other thread interrupts the current thread, and interruption of thread suspension is supported; or
- A "spurious wakeup" occurs.
In all cases, before this method can return the current thread must re-acquire the lock associated with this condition. When the thread returns it is guaranteed to hold this lock
关于java - 在可重入锁中等待条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12578687/