Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于Java生产者-消费者场景的问题_Java_Synchronization_Producer Consumer - Fatal编程技术网

关于Java生产者-消费者场景的问题

关于Java生产者-消费者场景的问题,java,synchronization,producer-consumer,Java,Synchronization,Producer Consumer,我知道类似的问题已经被问了很多次,但我花了一些时间阅读类似的问题,却找不到合适的答案 代码如下: public class Main { public static void main(String[] args) { Message message = new Message(); (new Thread(new Writer(message))).start(); (new Thread(new Reader(message))).start(); } }

我知道类似的问题已经被问了很多次,但我花了一些时间阅读类似的问题,却找不到合适的答案

代码如下:

public class Main {

  public static void main(String[] args) {
    Message message = new Message();
    (new Thread(new Writer(message))).start();
    (new Thread(new Reader(message))).start();
  }
}

class Message {
  private String message;
  private boolean empty = true;
  
  public synchronized String read() {
    while(empty) {
      try {
        System.out.println("Reader is waiting...relinquish the lock");
        wait();
      } catch(InterruptedException e) {
      }
    }
    empty = true;
    notifyAll();
    return message;
  }
  
  public synchronized void write(String message) {
    while(!empty) {
      try {
        System.out.println("Writer is waiting...relinquish the lock");
        wait();
      } catch(InterupptedException e) {
      }
    }
    empty = false;
    this.message = message;
    notifyAll();
  }
}


class Writer implements Runnable {
  private Message message;
  
  public Writer(Message message) {
    this.message = message;
  }

  public void run() {
    String messages[] = {
      // some message here
    };
    for(int i=0; i < messages.length; i++) {
      message.write(messages[i]);
    }
    message.write("Finished");
  }
}


class Reader implements Runnable {
  private Message message;
  
  public Reader(Message message) {
    this.message = message;
  }

  public void run() {
    for(String msg = message.read(); !msg.equals("Finished"); msg = message.read()) {
      System.out.println(msg);
  }
}

公共类主{
公共静态void main(字符串[]args){
消息消息=新消息();
(新线程(新写入程序(消息))).start();
(新线程(新读卡器(消息))).start();
}
}
类消息{
私有字符串消息;
私有布尔值为空=真;
公共同步字符串读取(){
while(空){
试一试{
System.out.println(“读卡器正在等待…放弃锁”);
等待();
}捕捉(中断异常e){
}
}
空=真;
notifyAll();
返回消息;
}
公共同步无效写入(字符串消息){
而(!空){
试一试{
System.out.println(“编写器正在等待…放弃锁”);
等待();
}捕获(InterupptedE异常){
}
}
空=假;
this.message=消息;
notifyAll();
}
}
类编写器实现可运行的{
私人信息;
公共编写器(消息){
this.message=消息;
}
公开募捐{
字符串消息[]={
//这里有消息吗
};
for(int i=0;i
我的理解是,在读线程的for循环中返回一个read()方法后,标志empty变为true,Writer线程被notifyAll()唤醒并准备运行,但读线程尚未放弃对Message对象的锁定,这意味着Writer无法调用synchronized write()方法,然后读取器线程应该再次调用read(),进入while循环,打印出“Reader is waiting…”消息,然后调用wait()放弃锁,这样编写器线程就可以继续获取锁并调用write()方法


但是从控制台中显示的输出消息来看,很多时候“Reader is waiting…”消息根本没有被打印出来,只有几次被打印出来。从上面的推理来看,这个消息不是应该在每次程序运行时都被打印出来吗?

所以我似乎忽略了线程通过调用wait()来放弃锁这一点或者离开监视器。当Reader的read()方法返回时,它将放弃对消息对象的锁定,因此编写器线程不必等到Reader线程在下一次迭代中调用wait()。我认为线程放弃锁定的唯一方法是调用wait(),显然我错了。因此,我似乎忽略了线程通过调用wait()或离开监视器来放弃锁的要点。当Reader的read()方法返回时,它会放弃消息对象上的锁,因此编写器线程不必等到Reader线程调用wait()为止在下一次迭代中,我认为线程放弃锁的唯一方法是调用wait(),显然我错了。