そのため、私はこの問題に丸一日苦労しており、いくつかのスレッド化チュートリアルと例を参照しても、まだ目的の結果を達成できていません。
私は、文字列の LinkedBlockingQueue をポーリングし、PrintWriter を使用してソケット経由で文字列をクライアントに配信することだけを行うスレッドを持っています。その機能は正常に動作していますが、接続の中断と再起動が発生した場合に適切に失敗できるようにすることで、機能を強化しようとしています. これを実現するために、スレッドで割り込みを呼び出してから参加し、Thread オブジェクトを再作成して最初からやり直すことを最終目標にしています。残念ながら、スレッドは join の呼び出しでハングします。これは、スレッドが実際に死ぬことは決してないことを意味するに違いありませんが、なぜそうなのかについて私は完全に当惑しています。以下の関連コード。
try {
resultSetStreamer.interrupt();
resultSetStreamer.join();
logger.info("Streamer finished.");
} catch (InterruptedException e) {}
実際のスレッド コード。
class ResultSetStreamer implements Runnable {
GZIPOutputStream gzos = null;
Socket clientSocket = null;
@Override
public void run() {
try {
logger.debug("Thread started.");
// Blocks and waits for an external connection.
clientSocket = serverSocket.accept();
// Creates a compression stream using best possible compression
// to the external connection.
gzos = new GZIPOutputStream(clientSocket.getOutputStream()) {
{
def.setLevel(compression);
}
};
PrintWriter toClient = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(gzos), bufferSize), false);
while (true) {
if (Thread.interrupted()) {
throw new InterruptedException();
}
if (moreRowsToReceive || !dataBuffer.isEmpty()) {
// Synchronisation point.
String row = dataBuffer.poll(pollTime,
TimeUnit.MILLISECONDS);
if (row != null) {
toClient.println(row);
logger.trace("Current row: " + ++currentCount + ".");
}
} else {
toClient.flush();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
gzos.finish();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
logger.debug("Thread finished.");
}
}
注目すべき主な場所は while(true) ループです。これは常にループし、スレッドが中断されたかどうかを確認する必要があります。その場合、スレッドを終了させるために、下部でキャッチされる例外をスローします。PrintWriter がコードの実行をブロックするべきではないと思います。どんな助けでも大歓迎です。