【问题标题】:wait() is a "if" block or a "while" block [duplicate]wait() 是“if”块或“while”块[重复]
【发布时间】:2014-05-16 04:11:24
【问题描述】:

以下代码复制自http://www.programcreek.com/2009/02/notify-and-wait-example/

我见过很多使用while循环来包装wait()的例子

我的问题: 在我第一次尝试解决类似问题时,我使用了 if 语句来包装 wait()。例如,

if(messages.size() == MAXQUEUE) {
        wait();
    }

用while循环代替if语句有什么好处?

import java.util.Vector;

class Producer extends Thread {

    static final int MAXQUEUE = 5;
    private Vector messages = new Vector();

    @Override
    public void run() {
        try {
            while (true) {
                putMessage();
                //sleep(5000);
            }
        } catch (InterruptedException e) {
        }
    }

    private synchronized void putMessage() throws InterruptedException {
        while (messages.size() == MAXQUEUE) {
            wait();
        }
        messages.addElement(new java.util.Date().toString());
        System.out.println("put message");
        notify();
        //Later, when the necessary event happens, the thread that is running it calls notify() from a block synchronized on the same object.
    }

    // Called by Consumer
    public synchronized String getMessage() throws InterruptedException {
        notify();
        while (messages.size() == 0) {
            wait();//By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep.
        }
        String message = (String) messages.firstElement();
        messages.removeElement(message);
        return message;
    }
}

class Consumer extends Thread {

    Producer producer;

    Consumer(Producer p) {
        producer = p;
    }

    @Override
    public void run() {
        try {
            while (true) {
                String message = producer.getMessage();
                System.out.println("Got message: " + message);
                //sleep(200);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        Producer producer = new Producer();
        producer.start();
        new Consumer(producer).start();
    }
}

【问题讨论】:

  • 你知道ifwhile语句的区别吗?
  • 令我惊讶的是,在重复问题的所有答案中,只有一个(我刚刚投票赞成)提到了虚假唤醒。这个问题的正确答案是“虚假唤醒”。
  • 是的,我知道其中的区别。我假设如果锁不可用, wait() 将停止当前线程。我的问题可以这样表述:如果线程停止,为什么要使用 while 循环,而不是 if 语句。

标签: java multithreading wait synchronized


【解决方案1】:

即使您没有主动通知正在等待的对象,wait() 也可能会返回(这在 documentation 中称为“虚假唤醒”)。这就是为什么将 wait() 调用包装到一个 while 循环中更有意义的原因,该循环检查您想要等待的实际条件是否得到满足,如果不满足则再次调用 wait(),而不是简单地假设当 wait( ) 返回您实际等待的事件已经发生。

【讨论】:

    【解决方案2】:

    当通知等待时,它将退出 if 循环并开始执行。 while 在这里更好,因为即使通知等待但队列已满,也不应该继续。所以它会一直等到队列为空。 我希望它能回答你的问题。

    【讨论】:

      猜你喜欢
      • 2015-02-16
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-04
      • 2021-07-27
      • 1970-01-01
      相关资源
      最近更新 更多