加入

时间:2016-05-16 22:34:07

标签: java multithreading concurrency java-threads

我有这个Transmitter类,它包含一个BufferedReader和一个PrintWriter。在主类上,想法是将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但我想在我的主类上多次使用它,如下所示:

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

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

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

2 个答案:

答案 0 :(得分:3)

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

正如Javadoc for BufferedReader.readLine()中强调的那样:

  

(返回)包含行内容的字符串,不包括任何行终止字符

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

答案 1 :(得分:1)

这样做:

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

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

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

doSomeWork();

新线程在这里没有任何实际意义。

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

第三,你的线程一直在循环中读取输入行,直到没有其他内容可读,除非另一方关闭流,否则它将阻塞readLine()调用。你将在getOutput()中看到的将是一个随机的行,恰好在你看的那一刻,下次你看它可能是同一行,或者是一些完全不同的行;如果没有你从主线程中注意到它,就会立即读取并忘记某些行。

当您真正需要从输入中获取新的行消息时,您可以直接在主线程中调用input.readLine(),您不需要额外的读取器线程。您可以将读取的消息存储到队列中,如yshavit建议的那样,如果这是可取的,例如出于性能原因,最好在消息可用时立即阅读并在内存中准备就绪。但是如果你只需要逐个阅读消息,那么你只需在实际需要的时候调用input.readLine()。