我正在研究通過網絡讀取和處理數據的應用程序。在測試程序的連接/斷開邏輯時,我注意到我的消費者線程在達到關閉狀態時未關閉。以下是消費者類的一個精簡版。調用interrupt()時不拋出InterruptedException的線程
import java.io.InputStream;
public class Consumer implements Runnable
{
private final InputStream input;
public Consumer(InputStream input)
{
this.input = input;
}
@Override
public void run()
{
byte readBuffer[];
readBuffer = new byte[1];
int goodData;
try
{
while(input.available() > 0)
{
goodData = input.read(readBuffer);
while (goodData > 0)
{
System.out.println(readBuffer[0]);
if (readBuffer[0] == 27)
{
System.out.println("Consumer: found closing byte and closing thread "+Thread.currentThread().getName());
//this is the last packet, so interupt thread to close
Thread.currentThread().interrupt();
//return;
//Thread.currentThread().stop(new InterruptedException("Attempting to close"));
}
goodData = input.read(readBuffer);
}
}
}
catch(Exception e)
{
System.out.println("closing "+Thread.currentThread().getName() +" because of an exception "+e.getClass());
return;
}
System.out.println("closing "+Thread.currentThread().getName());
}
}
我創建了一個虛擬主類來演示這個問題。
public class ExampleOfInterruptNotWorking
{
public static void main(String[] args)
{
byte[] bytesToWrite = new byte[]{0, 1, 2,3,4,5,6,65,23,65,21,54,13,54,1,76};
Consumer C;
Thread ConsumerThread;
PipedInputStream PIS = null;
PipedOutputStream POS = null;
try
{
PIS = new PipedInputStream();
POS = new PipedOutputStream(PIS);
C = new Consumer(PIS);
ConsumerThread = new Thread(C);
ConsumerThread.start();
POS.write(bytesToWrite);
POS.write(bytesToWrite);
bytesToWrite[1] = 27;
POS.write(bytesToWrite);
ConsumerThread.join();
}
catch(Exception e)
{
System.err.println("Unexpected exception in main");
e.printStackTrace(System.err);
}
finally
{
try
{
PIS.close();
POS.close();
}
catch(Exception ex)
{
//shouldn't happen in example
}
System.out.println("exiting main");
}
}
}
當您運行書面此代碼,消費者檢測到中斷,但直到管道是空不停止執行(不是我想要的)。只是嘗試,我改變了一個Thread.stop()調用,它做了我想要的,但我不想在生產代碼中留下它。我意識到我可以使用一個簡單的return語句,但這不是線程可以退出的唯一一點,我想要一些通用的退出代碼來清理資源。所以,我的問題是,消費者線程爲什麼不被打斷?對我來說能夠擁有共同的退出代碼有一個好方法嗎?
謝謝!
,因爲它沒有等待這不是打斷你並沒有把它的消息。好的方法是在完成寫作時關閉流。 – 2012-08-16 12:05:37
返回聲明看起來像你最好的選擇。你能否試圖證明你說你不能創建「清理資源的一些常見退出代碼」的問題?通常,你在finally塊中這樣做。 – 2012-08-16 12:06:09
@RomanC我真的不喜歡在正在讀取它們的東西下面關閉流。在這種特殊情況下,我收到了關閉連接請求的返回消息。在設計應用程序的過程中,我不能保證收到的信息是最後發送的信息。正如它在下面發佈的「異常是例外情況」和關閉流會導致IOException - 當我已經知道流正在關閉。 – adeady 2012-08-16 12:20:33