2012-11-28 60 views
0

我有一個線程的異常(假設T1)從插座中讀取數據:Java Socket技術 - 如何捕捉BufferedReader.readline()

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處於活動狀態並正在運行到假套,關閉套接字
  • 上下文切換
  • 因爲T1被阻擋和T2關閉套接字,T1拋出異常。我想要的是捕捉這個SocketException。我不能在T1.run()中放置try/catch(SocketException)。那麼我怎樣才能在T1的運行方法中捕捉到它呢?如果在T1的運行中無法捕捉它,那我怎麼能在其他地方捕捉到它?

PS:
「有關線程調試另一個問題」通常當調試代碼分步實施,就失去一個上下文切換的「活性移動線」。假設我在T1的第20行,發生了上下文切換,我們假設程序從T2的第30行繼續,但調試器不會顯示到T2的第30行,而是顯示「主動運行行'消失了。所以我失去了對代碼的控制。我使用Eclipse for Java和Visual Studio for C#。那麼在調試上下文切換時跟蹤代碼的最佳方式是什麼?

+1

'SocketException'擴展了'IOException'。所以你的'catch'子句應該捕獲'SocketException'。 – reprogrammer

+0

爲什麼你不能在T1的'run()'方法中捕獲'SocketException'? (它是'IOException'的一個子類,所以它會被現有的'catch'子句捕獲,如果你想分別捕獲它,你只需要在早期的'catch'子句中列出它。) –

+0

我知道。但不知何故,我不知道爲什麼,該計劃沒有抓住它。我的意思是我在那裏放置了一個斷點,但程序永遠不會在catch塊中停止。 –

回答

1

對於你的問題,假設你正在使用線程池,也許你應該創建一個ThreadFactory,在所有線程上安裝一個Thread.UncaughtExceptionHandler,然後用ExecutorService上的execute()調用你的工作,而不是submit()。

對於你的問題進行調試也許你應該閱讀 http://msdn.microsoft.com/en-us/library/ms164746.aspx

1

你的代碼中有幾個其他問題,所以我會在同一時間解決它們。

  1. 您必須創建BufferedReader循環。否則,每次在循環中都會丟失緩衝區中的數據。
  2. 您必須測試readLine()的結果爲空。如果你得到它,你必須關閉BufferedReader並退出循環。
  3. 如果您遇到任何異常,您還必須關閉BufferedReader並退出循環。

我想要的是抓住這個SocketException。

所以趕上它。

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

您必須。沒有選擇。由於上述內容,您必須完全重寫。