【问题标题】:How to implement a Reader/Writer program using threads?如何使用线程实现 Reader/Writer 程序?
【发布时间】:2020-04-05 02:27:34
【问题描述】:

我的阅读器/写入器实现存在问题。我应该编写一个 Reader 类,该类从控制台获取一个 String 并将其添加到 Queue 和一个 Writer 类,该类使用 Threads 从同一队列中删除 String 并将其输出到控制台。我只为一个字符串编写了我的程序(输入一个字符串并通过队列输出该字符串)并且效果很好。现在我正在努力做到这一点,以便我可以输入多个字符串,按 Enter,然后阅读器将其添加到队列中,然后编写器显示它。如果键入字符串quit,则两个线程都必须停止并且程序应该结束。

我的读者想法是这样的:

Scanner k = new Scanner(System.in);
in = k.nextLine();
if(in.equals("quit"))
  System.exit(0);

synchronized(q){
  while(!(in.equals("quit"))){
    // System.out.println(q.isEmpty());
    q.enqueue(in);
    in = k.next();
    if(in.equals("quit"))
      System.exit(0);
  }
}

我的 Writer 看起来像这样:

public void run(){
  synchronized(q){
    while(!q.isEmpty()){
      String out = q.dequeue();
      System.out.println(out);
    }
  }
}

我的阅读器似乎工作正常,因为我在添加到队列后内置了Sys.out.(q.isEmpty)。它向我显示队列正在填满,但没有任何内容从 Writer 类输出到控制台。写quit 停止程序没有问题。

我不认为我完全理解线程。我的主要方法只是使用Thread t1 = new Thread(new Reader(queue)); 创建线程,并为Writer 创建相同的线程,然后启动两个线程。

【问题讨论】:

  • 提醒我,开学已经有一段时间了:Reader/Writer 涉及到 reader 的 read lock,以及 writer 的 write lock(排他锁),对吗?我看不出你是如何通过这样一个简单的同步块来实现的。

标签: java loops java-threads reader writer


【解决方案1】:
synchronized(q){
  while(!(in.equals("quit"))){
    // System.out.println(q.isEmpty());
    q.enqueue(in);
    in = k.next();
    if(in.equals("quit"))
      System.exit(0);
  }
}

这个同步块太大了。通常,您希望同步时间尽可能短。进出。同步的时间越长,其他线程被阻塞的时间就越长。

在同步时执行用户输入是禁忌。不应因为用户的打字速度慢而阻塞其他线程。

更糟糕的是,您已经在同步块中获得了整个程序的循环。坏读者!如此贪婪。在用户输入所有输入并键入“退出”之前,它不会放弃q 锁定。只有这样它才会释放锁并让编写器继续。

while(!(in.equals("quit"))){
  // System.out.println(q.isEmpty());
  synchronized(q){
    q.enqueue(in);
  }
  in = k.next();
  if(in.equals("quit"))
    System.exit(0);
}

作者有一个不同的致命缺陷。一旦队列为空,它就会退出。不过,队列很多时候都是空的,不是吗?当它是作家不应该只是死。

一个快速的解决方法是将整个东西包裹在一个无限循环中:

public void run(){
  while (true) {
    synchronized(q){
      while(!q.isEmpty()){
        String out = q.dequeue();
        System.out.println(out);
      }
    }
  }
}

它会让作者保持活力。但它也会消耗 CPU 时间,循环数百万次,而该死的用户会慢慢地敲击键盘。如果您检查系统监视器,您会看到程序的 CPU 使用率达到 100%。不太好。

解决此问题有点超出本问答的范围。简短的回答是使用wait() and notify() 让作者进入睡眠状态,直到有可用内容为止。

【讨论】:

  • 嘿,非常感谢!对我来说很清楚我还没有完全得到线程,但是你的一句话确实让我理解了很多 - “它没有放弃 q 锁” - 我没有那样想,但我认为我现在更了解它了。至于表现,谢谢指出,但我的课程根本没有讲过这样的事情;我想它会在以后出现。感谢您提供有关 waitnotify 的链接 - 我会检查一下!干杯。
猜你喜欢
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
  • 2014-01-16
  • 2017-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多