私は、ネットワークを介してデータを読み取って処理するアプリケーションに取り組んでいます。プログラムの接続/切断ロジックをテストしているときに、コンシューマースレッドがクローズ状態に達したときにクローズしていないことに気付きました。以下は、コンシューマークラスの簡略版です。
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ステートメントを使用できることに気付きましたが、スレッドが終了できるのはこれだけではありません。リソースをクリーンアップする一般的な終了コードが必要です。だから、私の質問は、なぜコンシューマースレッドが中断されないのですか?共通の終了コードを使用できるようにするための良い方法はありますか?
ありがとう!