初学者';s关于Java中多线程以及使用同步块和wait()的问题/notify()

初学者';s关于Java中多线程以及使用同步块和wait()的问题/notify(),java,multithreading,wait,synchronized,notify,Java,Multithreading,Wait,Synchronized,Notify,我正在学习Java中的同步机制。这是我要分析的示例代码。很抱歉丢失了代码,但故事很简单。我们有2个消费者和4个生产者,他们实现为线程,他们在while循环中分别调用这些get和put方法 问题是为什么我们会陷入僵局? 另外,如果你能回答我心中的一些问题 处理与notify和wait进行通信的线程的监视器和负责确保没有两个线程进入同步方法(get或put)的监视器之间有什么区别?也就是说,当put方法内的一个线程调用notify()时,等待进入put方法内的另一个线程是否是接管监视器的有效候选线程

我正在学习Java中的同步机制。这是我要分析的示例代码。很抱歉丢失了代码,但故事很简单。我们有2个消费者和4个生产者,他们实现为线程,他们在while循环中分别调用这些get和put方法

问题是为什么我们会陷入僵局? 另外,如果你能回答我心中的一些问题

  • 处理与notify和wait进行通信的线程的监视器和负责确保没有两个线程进入同步方法(get或put)的监视器之间有什么区别?也就是说,当put方法内的一个线程调用notify()时,等待进入put方法内的另一个线程是否是接管监视器的有效候选线程

  • 我的主要问题的答案是否如此“明显而愚蠢”,以至于当一个线程位于方法put的wait()内时,没有其他线程可以同时进入这两个方法put并获取通知,从而导致死锁发生

  • notify和notifyAll之间有什么区别

    public synchronized void put(Object o) throws InterruptedException {
        while (count == size) {
            wait();
        }
        buf[in] = o;
        //System.out.println("PUT from " + Thread.currentThread().getName());
        ++count;
        in = (in + 1) % size;
        notifyAll(); // if this is not a notifyAll() we might notify the wrong waiter
      }
    
    public synchronized Object get() throws InterruptedException {
       while (count == 0) {
           wait();
       }
       Object o = buf[out];
       buf[out] = null;
       //System.out.println("GET from " + Thread.currentThread().getName());
       --count;
       out = (out + 1) % size;
       notifyAll(); // if this is not a notifyAll() we might notify the wrong waiter
       return (o);
    }
    
  • 我的主要问题的答案是否如此“明显而愚蠢”,以至于当一个线程位于方法put的wait()内时,没有其他线程可以同时进入这两个方法put并获取通知,从而导致死锁发生

    o.wait()
    执行一系列步骤:

    • 它会释放
      o
      上的锁
    • 它等待另一个线程调用
      o.notify()
    • 它将等待直到锁再次可用
    • 它重新锁定锁,然后最后
    • 它回来了

    因此,当一个线程在
    put(o)
    调用中执行
    wait()
    调用时,另一个线程可以在
    get()或
    put()中执行
    打电话。

    我想如果给你这个来分析的话,也许你应该做你自己的工作。关于#3,我想你应该做关于监视器,我想你还需要了解它们是如何工作的。我很确定答案在第二位,这使我的正式工作得以完成。这不是我的错,我没有这门课的官方文献,我的“自己的作品”是谷歌搜索,在很长一段时间没有关于第一个问题的运气后,我决定自己问这个问题。当我已经在这里的时候,我想问第二和第三个问题。当我在网上发帖“了解更多”时,不需要那种态度。如果你不想回答,你可以跳过这一页。在现实世界中,阅读文档是正常的,也是意料之中的。对于你的问题,我关心的是你的“谁监控…”和“谁监控…”几乎可以肯定这里只使用了一个监控。您应该检查代码,确保您有信心了解有多少监视器在使用,以及它们与什么对象相关。此外,我觉得我应该谈谈“教学上的不当行为”。如果您真的是一个编码初学者(不仅仅是Java),那么是的,这个问题非常难回答。如果你更高级,这个问题是一个很好的例子,说明你为什么要像Brian Goetz建议的那样使用API;它精确地显示了notify/wait的锐边(尤其是notify与notifyAll)。