我有以下代码:
public class Synchronizer {
private final Lock lock = new ReentrantLock();
private final Condition done = lock.newCondition();
private boolean isDone = false;
private void signalAll() {
lock.lock(); // MUST lock!
try {
isDone = true; // To help the await method ascertain that it has not waken up 'spuriously'
done.signalAll();
}
finally {
lock.unlock(); // Make sure to unlock even in case of an exception
}
}
public void await() {
lock.lock(); // MUST lock!
try {
while (!isDone) { // Ascertain that this is not a 'spurious wake-up'
done.await();
}
}
finally {
isDone = false; // for next time
lock.unlock(); // Make sure to unlock even in case of an exception
}
}
}
假设线程1调用synchornizer.await()并通过
获取锁定lock.lock();
和
上的阻止done.await();
然后另一个线程2调用synchronizer.signalAll()以发信号通知线程1.我的问题是线程2如何能够通过调用
来获取锁定lock.lock();
之前打电话
done.signallAll();
当线程1最初获取锁定时?
我在这里找到了同样的问题:
Waiting on a condition in a reentrant lock
答案是:
Lock和synchronized都暂时允许其他人获取锁定 等他们的时候要停止等待,线程必须重新获取 锁。
我试图理解这是否意味着如果线程1没有调用done.await(),线程2将无法获取锁定?
答案还说明了:
注意:它们不会完全释放它,如果您采用堆栈跟踪 可以有多个线程似乎一次持有锁, 但最多其中一个将运行(其余的将等待)
然而,Condition.await()的文档声明:
与此条件关联的锁定以原子方式释放
锁是否被释放以及“他们没有完全释放”是什么意思?
答案 0 :(得分:1)
T1可能是"虚假的醒来"在运行T2的任何时候。但这将在done.await调用中发生。除非相关的锁被解锁且其他释放条件不正确(线程必须发出信号或中断),否则控制将永远不会被调回到调用者代码。