如何使用资源尝试将while循环放入线程中?

Posted

技术标签:

【中文标题】如何使用资源尝试将while循环放入线程中?【英文标题】:how do I put a while loop into a thread, using try with resources? 【发布时间】:2013-12-12 09:41:57 【问题描述】:

如何将while 循环放入线程中?

public class Weather 

    public static void main(String[] args) throws UnknownHostException, IOException 
        String host = "rainmaker.wunderground.com";
        int port = 3000;
        int byteOfData;
        
            try (Socket socket = new Socket(host, port);
                    InputStream inputStream = socket.getInputStream();
                    OutputStream ouputStream = socket.getOutputStream();
                    PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
                    final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) 
                //also, a thread for reading from stdin
                Thread remoteOutputStream = new Thread() 
                    @Override
                    public void run() 
                        //while loop should go here
                        //   java.net.SocketException: Socket closed
                        //why does this error occur?
                    
                ;
                remoteOutputStream.start();
                while ((byteOfData = inputStream.read()) != -1)   //put into thread
                    out.print((char) byteOfData);
                
            
        
    

当我将while 循环放入线程时,它只会抛出java.net.SocketException: Socket closed,因为大概是try with resources works 的原因。但是,我不知道如何使用这种尝试的线程。

因为会有多个线程,一个用于读取本地InputStream,一个用于远程OutputStream,似乎有必要将线程放入try,反之亦然..?

【问题讨论】:

【参考方案1】:

将整个try with resources语句放入线程中

final String host = "rainmaker.wunderground.com";
final int port = 3000;


  Thread remote = new Thread()
  
    @Override public void run()
    
      try (Socket socket = new Socket(host, port);
          InputStream inputStream = socket.getInputStream();
          OutputStream ouputStream = socket.getOutputStream();
          PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
          final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)))
      
        int byteOfData;

        while ((byteOfData = inputStream.read()) != -1)
         //put into thread
          out.print((char)byteOfData);
        
      
    
  ;
  remote.start();

【讨论】:

doh,我一如既往地问错了问题。这更有意义,你的方式:) 出于好奇,假设这是解决方案,为什么它不起作用? 因为inputStreambyteOfData 在单独的线程中 嗯,我的结局更糟(到目前为止)。另外,我需要一个线程来读取打开的流,并且需要一个线程来写入打开的流。 什么是“更糟糕的混乱”? 让它运行起来,谢谢。语法让我很困惑。【参考方案2】:

类似的东西(可能需要整理):

public static void main(String[] args) throws UnknownHostException, IOException 
    String host = "rainmaker.wunderground.com";
    int port = 3000;
    int byteOfData;
    
            //also, a thread for reading from stdin
            Thread remoteOutputStream = new Thread() 
                @Override
                public void run() 
                    try (Socket socket = new Socket(host, port);
                        InputStream inputStream = socket.getInputStream();
                        OutputStream ouputStream = socket.getOutputStream();
                        PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
                        final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) 
                       while ((byteOfData = inputStream.read()) != -1)   //put into thread
                           out.print((char) byteOfData);
                       
                     catch (CATCH EXCEPTIONS HERE) 
                       // Handle errors here
                    
            ;
            remoteOutputStream.start();
        
    

如果您需要分离线程,那么您将需要类似BlockingQueue 的东西,让一个线程读取并推送到队列 - 另一个从队列中读取并写入。

不过,我看不出有什么理由让您有两个线程来执行此操作。

【讨论】:

远程一个线程,本地一个线程。然后在线程之间传递消息……可怜的 telnet 客户端。 我收到大量未报告的异常,但不知道如何捕获它们。 如果一个是远程的,那么它将是一个单独的程序(或另一个副本),没有额外的线程

以上是关于如何使用资源尝试将while循环放入线程中?的主要内容,如果未能解决你的问题,请参考以下文章

Android:如何将对话框放入循环中

逐行读取Javascript中的.csv文件,并使用while循环将其放入数组中

如何优雅的使用和理解线程池

qt多线程的问题

如何结束带有 for 循环的 while 循环?

While 循环计时如何在带有多个线程的 C# 中工作?