【问题标题】:java + can we miss signals using wait and notify?java + 我们可以使用等待和通知错过信号吗?
【发布时间】:2013-06-06 14:24:24
【问题描述】:

semaphore tutorial 中摘录说:

使用这样的信号量可以避免错过信号。您将调用 take() 而不是 notify() 和 release() 而不是 wait()。如果对 take() 的调用发生在对 release() 的调用之前,则调用 release() 的线程仍然知道调用了 take(),因为信号内部存储在信号变量中。 wait() 和 notify() 不是这种情况。

我们不能单独使用等待和通知来避免丢失的信号吗?

【问题讨论】:

  • 否,例如,如果notify() 被调用之前 wait()

标签: java multithreading semaphore


【解决方案1】:

如果您有两个线程,其中一个调用notify(),然后另一个调用wait(),则可能会出现丢失信号。避免这种情况发生的唯一方法是设置某种屏障,使第二个线程等待第一个线程调用notify() - 可用于创建此屏障的一种机制是信号量:)

【讨论】:

    【解决方案2】:

    等待并通知您应该始终

    • 根据条件等待
    • 通知等待检查的状态发生了哪些变化。

    注意:wait() 可能会虚假唤醒,因此您不能假设调用了 notify()。

    我们不能单独使用等待和通知来避免丢失的信号吗?

    不,你永远不可能,这就是为什么它总是被认为与状态变化有关。

    例如一个常见的面试问题是写一个简单的阻塞队列。

    // 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 你能展示一些示例代码来让彼得更清楚吗?
    猜你喜欢
    • 2021-09-10
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    相关资源
    最近更新 更多