2

私はいくつかの行動を理解しようとしています。1 つのスレッドを生成するコードがいくつかあります。しばらく待ってから中断し、参加してからメソッドを終了します。

.
.
.
try {
        Thread.sleep(processForMillis);
    }
    catch (InterruptedException ex) {
        // Won't happen, ignore.
    }

    for (Thread t : threads) {
        logger.debug("Interrupting Thread " + t.getName());
        t.interrupt();
    }

    for (Thread t : threads) {
        try {
            t.join(1000L);
            logger.debug("Joined Thread " + t.getName());
            logger.debug("isAlive? " + t.isAlive());
        }
        catch (InterruptedException ex) {
            // this will never happen
            logger.debug("InterruptionException while joining, but didn't expect it.");
        }
    }
} // end of method

現在、これを 1 つのスレッドで実行しています。通常、参加後に isAlive() が false になることをログで確認できますが、まだ生きている場合もあります。スレッドは while ループに入っています:

while(!Thread.currentThread().isInterrupted()){
.
// do some blocking io stuff here
}

したがって、スレッドが入力ストリームの読み取り/処理中にスレッドを中断し (io をブロック)、while 条件を押して結合を終了するのにかかる時間よりも多くの時間がかかっていると思われます。

私の質問は、スレッドはどうなりますか?

スレッドは参照されなくなり、スレッドをガベージ コレクションできますが、どのリソースも適切にクリーンアップされておらず、問題があるようです。NIO に切り替える以外に、これに適したパターンはありますか?

4

2 に答える 2

1

interrupt() は、スレッドが中断されたことを示すフラグをスレッドに設定するだけです。多くのブロッキング呼び出しは、これが発生してもブロックを解除しません。つまり、スレッドは割り込みの影響をほとんど受けず、その処理を続けます (たとえば、InputStream でのブロック)。

スレッドがブロックを解除せず、指定された結合タイムアウト (ここでは 1 秒) で while 条件にヒットしない場合もあれば、タイムアウト内にブロッキング呼び出しが完了してスレッドが終了する場合もあると思います。

スレッドが実行されている限り、スレッドにはまだ参照があり、ガベージ コレクションは行われません。ブロッキング呼び出しがブロック解除されない場合 (たとえば、もう一方の端が静かに消えたデッド tcp ソケットから読み取った場合に発生する可能性がある)、スレッドは決して終了しない可能性があります。

于 2010-01-29T16:39:59.803 に答える
0

nosの答えに加えて、ブロッキングIO呼び出しを中断するには、close()そのストリームを実行できます

于 2010-01-29T16:51:33.587 に答える