java.util.concurrent.locks.Condition 是如何工作的?
How do java.util.concurrent.locks.Condition work?
阅读Java8关于java.util.concurrent.locks.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();
}
}
}
所以我的主要问题是:条件如何运作?
- 它是否在开始等待时释放锁? (例如
notFull.await()
)?
- 不同的线程能否获取同一个锁并移动直到
signal()
一个条件,唤醒其他线程?
- 我认为这个例子会导致死锁,因为如果一个线程正在等待缓冲区不为空并且它还没有释放锁,另一个怎么能线程获取锁,清空缓冲区,
signal()
现在满足条件,然后释放锁如果等待缓冲区未满的线程尚未释放锁?
这些是初学者的问题。请帮帮我。
谢谢。
- 对对对,只要等待一个条件,就释放锁。
await/signal/signalAll
实际上与 wait/notify/notifyAll
具有相同的行为
- 不,ReentrantLock 是排他锁,因此只有一个线程可以获得锁。
- 参见#1。当一个线程调用
signal
或signalAll
时,它会分别释放一个线程或所有等待相应Condition
的线程,这样该线程或这些线程才有资格再次获得锁。但是现在锁仍然由调用 signal
或 signalAll
的线程拥有,直到它通过调用 lock.unlock
显式释放锁。然后 has/have 被释放的线程将能够再次尝试获取锁,可以获取锁的线程将能够再次检查条件(这次条件我的意思是 count == items.length
或本例中的 count == 0
),如果可以,它将继续,否则它将再次 await
并释放锁以使其可用于另一个线程。
阅读Java8关于java.util.concurrent.locks.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();
}
}
}
所以我的主要问题是:条件如何运作?
- 它是否在开始等待时释放锁? (例如
notFull.await()
)? - 不同的线程能否获取同一个锁并移动直到
signal()
一个条件,唤醒其他线程? - 我认为这个例子会导致死锁,因为如果一个线程正在等待缓冲区不为空并且它还没有释放锁,另一个怎么能线程获取锁,清空缓冲区,
signal()
现在满足条件,然后释放锁如果等待缓冲区未满的线程尚未释放锁?
这些是初学者的问题。请帮帮我。
谢谢。
- 对对对,只要等待一个条件,就释放锁。
await/signal/signalAll
实际上与wait/notify/notifyAll
具有相同的行为
- 不,ReentrantLock 是排他锁,因此只有一个线程可以获得锁。
- 参见#1。当一个线程调用
signal
或signalAll
时,它会分别释放一个线程或所有等待相应Condition
的线程,这样该线程或这些线程才有资格再次获得锁。但是现在锁仍然由调用signal
或signalAll
的线程拥有,直到它通过调用lock.unlock
显式释放锁。然后 has/have 被释放的线程将能够再次尝试获取锁,可以获取锁的线程将能够再次检查条件(这次条件我的意思是count == items.length
或本例中的count == 0
),如果可以,它将继续,否则它将再次await
并释放锁以使其可用于另一个线程。