【发布时间】:2021-12-14 00:10:42
【问题描述】:
Java 文档来自这里https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html
我正在尝试理解条件概念。在下面的代码中,将两者都放在同一个锁上等待。文档说,在调用任何 condition.await() 之前,我们需要获取相应的锁 (here line 2 : final Lock lock = new ReentrantLock();).
我的问题是,假设缓冲区已满。在这种情况下,如果我们尝试插入一个对象,线程将被阻塞直到count == items.length,但这里的锁仍然保留在试图放入的线程中。我们如何调用方法 take() 来减少计数,因为 take() 需要获取同一个 Lock 的持有。在我看来,这将是死锁,因为无法调用 take(),如果项目为空,我们将无法调用 put(),因为现在锁已经使用 take()。
如果我遗漏了什么,请帮助我理解。提前致谢。
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();
}
}
}
【问题讨论】:
-
await()-javadoc:“与此条件关联的锁被自动释放,当前线程出于线程调度的目的而被禁用,并且处于休眠状态,直到发生以下四种情况之一:...”,还请“小字”;)
标签: java multithreading blocking locks