Java 加入后线程卡住了

Java thread stuck after join

我有这个 Transmitter class,它包含一个 BufferedReader 和一个 PrintWriter。这个想法是,在主 class 上,对主套接字使用 Transmitter.receive() 和 Transmitter.transmit()。问题是:

 public void receive() throws Exception {
      // Reads from the socket
      Thread listener = new Thread(new Runnable() {
        public void run() {
          String res;

          try {
            while((res = input.readLine()) != null) {
              System.out.println("message received: " + res);

              outputMessage = (res);

            if (res.equals("\n")) {
              break;
            }
           }
        } catch (IOException e) {
          e.printStackTrace();
        }
      };
    });

    listener.start();
    listener.join();
  }

线程更改了 'outputMessage' 值,我可以使用辅助方法获取该值。问题是,如果没有加入,我的客户端会得到 outputMessage 但我想在我的主 class 上多次使用它,如下所示:

trans1.receive();
while(trans1.getOutput() == null);
System.out.println("message: " + trans1.getOutput());

但是加入这个 system.out 永远不会执行,因为 trans1.receive() 被卡住了...有什么想法吗?

编辑 1:这里是发射机 class https://titanpad.com/puYBvlVery

您可以发送\n;这并不意味着您会在 Java 代码中看到它。

正如 Javadoc for BufferedReader.readLine() 中所说(强调我的):

(Returns) A String containing the contents of the line, not including any line-termination characters

所以 "\n" 将永远不会返回。

这样做:

{
  Thread listener = new Thread(new Runnable() {
    public void run() {
      doSomeWork();
    };
  });

  listener.start();
  listener.join();
}

将创建一个新线程,然后等待它完成工作并完成。因此,它或多或少与直接执行相同:

doSomeWork();

新线程在这里没有任何实际用途。

此外,额外的线程会引入同步问题,因为在您的代码中您无法确保您的变量是同步的。

第三,您的线程一直在循环中从输入中读取行,直到没有更多内容可读为止,除非另一端关闭流,否则它将阻塞 readLine() 调用。您将在 getOutput() 中看到的是一条随机线,它恰好在您查看的那一刻就在那里,下次您查看时可能是同一行,也可能是一些完全不同的行;有些行会被立即阅读和遗忘,而你从主线程中没有注意到它。

当您确实需要从输入中获取换行消息时,您可以直接在主线程中调用 input.readLine(),不需要额外的 reader 线程。如果需要,您可以按照 yshavit 的建议将读取的消息存储到队列中,例如出于性能原因,最好在消息可用时立即读取消息并在内存中准备好它们。但是,如果您只需要一条一条地阅读消息,那么您只需在真正需要时调用 input.readLine() 即可。