【问题标题】:calling Object.notify() before Object.wait()在 Object.wait() 之前调用 Object.notify()
【发布时间】:2011-09-28 22:40:27
【问题描述】:

如果没有线程在等待,使用 Object.wait() ,对 Object.notify()Object.notifyAll() 的任何调用都无效。我有一个场景,如果我在等待集为空时调用Object.notify(),随后对Object.wait() 的调用不应该让线程等待。如何实现?信号量可能是我能想到的一种解决方案。有没有更优雅的解决方案?

【问题讨论】:

    标签: java concurrency operating-system


    【解决方案1】:

    我是这样实现的

    线程 A:

     req.run();
    synchronized (req) {
                        try {
                            req.wait(3000);
                            rawResponse = eq.ReturnXML;
                            logger.info("[" + refID + "] Response recieved: " + rawResponse);
                            responseRecieved = true;
                            req.notify();
                        } catch (InterruptedException ex) {
                            logger.error("Error waiting on req", ex);
                        }
                    }
    

    线程 B:

    synchronized (req) {
            while (!responseRecieved) {
                try {
                    req.wait(3000);
                } catch (InterruptedException ex) {
                    logger.error("Error waiting on req while trying to get state", ex);
                }
            }
        }
    

    线程 A 发出请求并等待响应,同时线程 B 只等待响应。如果响应已经到达,它不会等待。

    【讨论】:

      【解决方案2】:

      这种情况似乎非常适合Semaphore。调用Semaphore.release() 而不是notify()Semaphore.acquire() 而不是等待。

      【讨论】:

        【解决方案3】:

        我会使用SemaphoreCyclicBarrierCountDownLatch - 以更适合您的实际情况为准。我认为重用现有抽象而不是自己使用低级机制是一个好主意,除非这些机制能够为您提供您想要的行为(在这种情况下它们没有)。

        【讨论】:

        • 感谢您的好建议。我想 Semaphore 最适合我的场景。
        【解决方案4】:

        使用标志来指示通知。在进入等待之前阅读标志并采取相应的行动。

        boolean stopped = false;
        
        public void run(){
           synchronized(object){
              while(!stopped)
                object.wait();
           }
        
        }
        
        public void stop(){
          synchronized(object){
            stopped=true;
            object.notify();
          }
        
        }
        

        【讨论】:

        • 感谢您的快速回复。
        • +1:任何状态变化都可以记录早前调用了 notify() 的事实。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多