使用这样的信号量可以避免错过信号。您将调用take()而不是notify()和release()而不是wait()。如果在调用release()之前调用take(),调用release()的线程仍然会知道调用了take(),因为信号内部存储在信号变量中。 wait()和notify()不是这种情况。
我们不能单独使用等待和通知来避免错过的信号吗?
答案 0 :(得分:3)
等待并通知您应始终
注意:wait()可能会虚假唤醒,因此您无法假设调用了notify()。
我们不能单独使用等待和通知来避免错过的信号吗?
不,你永远不可能这就是为什么总是假设它会与状态变化相关联。
e.g。一个常见的面试问题是编写一个简单的阻塞队列。
// a simple blocking queue using an AtomicReference
final Object lock = new Object();
final E eRef = null;
public void push(E e) {
synchronized(lock) {
while(eRef != null)
lock.wait();
eRef = e;
lock.notifyAll();
}
}
public E take() {
synchronized(lock) {
while(eRef == null)
lock.wait();
E e = eRef;
eRef = null;
lock.notifyAll();
return e;
}
}
答案 1 :(得分:3)
如果您有两个线程,其中一个线程在另一个线程notify()
之前调用wait()
,则会发生丢失信号。避免这种情况发生的唯一方法是使某种障碍使第二个线程等到第一个线程调用notify()
- 一个可用于创建此障碍的机制是信号量:)