Java Socket - 如何捕获BufferedReader.readline()的异常

时间:2012-11-28 05:01:58

标签: java multithreading sockets

我有一个Thread(假设是T1)从socket中读取数据:

public void run() {
  while (running) {
    try {
      BufferedReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream()) ); 
      String input = reader.readLine();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}

另一个线程(比方说T2)尝试在其中一个方法中完成程序。因此T2执行以下操作:

T1.running = false;
socket.close();

以下是我无法找到解决方案的情况:

  • T1处于活动状态并等待某些输入读取即阻塞。
  • 上下文切换
  • T2处于活动状态并将运行设置为false,关闭套接字
  • 上下文切换
  • 因为T1阻塞而T2关闭了套接字,T1会抛出异常。我想要的是捕获这个SocketException。我不能在T1.run()中放一个try / catch(SocketException)。那么我怎样才能在T1的运行方法中捕获它?如果在T1的运行中无法捕捉到它,那我怎么能在别处赶上它?

PS:“关于线程调试的另一个问题”
通常,当我逐步调试代码时,我在上下文切换上丢失了“活动运行线”。假设我在T1的第20行,发生上下文切换,让我们假设程序从T2的30.line继续,但是调试器不会显示/显示到T2的30.line,而是'active running line '消失了。所以我失去了对代码的控制权。我使用Eclipse for Java和Visual Studio for C#。那么在上下文切换时调试时跟踪代码的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

假设您正在使用线程池,那么您应该创建一个ThreadFactory,在所有线程上安装Thread.UncaughtExceptionHandler,然后在ExecutorService上调用execute()而不是submit()。

对于调试问题,您应该阅读 http://msdn.microsoft.com/en-us/library/ms164746.aspx

答案 1 :(得分:1)

您的代码还有其他几个问题,所以我会同时解决所有这些问题。

  1. 您必须在循环外部创建BufferedReader 。否则,每次在循环中丢弃的缓冲区中都会丢失数据。
  2. 您必须将readLine()的结果测试为null。如果你得到它,你必须关闭BufferedReader并退出循环。
  3. 如果您遇到任何异常,您还必须关闭BufferedReader并退出循环。
  4.   

    我想要的是抓住这个SocketException。

    所以抓住它。

      

    我不能在T1.run()中放置try / catch(SocketException)。

    你必须。没有选择。由于以上各项,你必须完全重写它。