3

何らかの理由で、私は次のことに混乱しています。処理が完了した後に絶対に実行する必要
があると仮定します。 これを行う方法は、に参加することです。 簡単な例: Thread AThread B
Thread AThread B

public class MainThread {  
    public static void main(String[] args){   
        Thread b = new Thread (new SomeRunnable(args[0]));  
        b.start();  
        try {   
            b.join();   
        } catch(InteruptedException e) {  
        }  
        // Go on with processing  
    }
}

私の質問は次のとおりです。そのような場合に例外を処理する適切な方法は何ですか?

私が見たさまざまな例では、教科書でも例外は無視されます。
それで、続行する前にそれが完全に終了Thread Aしていることを確認する必要がある場合、例外のためにキャッチに終わった場合、それはまだ実際に実行可能/実行可能である可能性がありますか?では、この例外を処理するための最良の方法は何ですか?Thread BThread B

4

2 に答える 2

2

まず、この例外がスローされる原因を理解する必要があります。スレッドの呼び出しstop()は現在非推奨です。代わりに、スレッドを停止したい場合は、を呼び出してスレッドを中断thread.interrupt()します。これはスレッド(!)に影響を与えません。スレッドは時々interruptedフラグを明示的にチェックし、正常に処理を停止する必要があります。

ただし、スレッドがスリープしている場合、ロックまたは別のスレッドで待機している場合(join()例のように使用する場合)、このフラグをすぐにまたは十分な頻度でチェックすることはできません。join()このような場合、JVMは、誰かが割り込みを試みたことをスレッドに通知するブロッキングメソッド(そのまま)から例外をスローします。通常、その例外は無視できます(つまり、ログに記録しないでください)。重要なのは副作用です。たとえば、ループから抜け出します。

public void run() {
    try {
        while(!isInterrupted()) {
            Thread.sleep(1000);
            //...
    } catch(InterruptedException e) {
        //no need to log it, although it's a good idea.
    }
}

その例外をログに記録しなかったのは問題ではありませんが、ループから脱出し、スレッドを効果的に終了しました。

さて、あなたの質問に戻りましょう。割り込みが発生した場合Thread Aは、他のスレッドがそれを終了するように要求したことを意味します。おそらく、JVM全体がシャットダウンしたか、Webアプリケーションがアンデプロイされているためです。この場合、クリーンアップ以外は何もしてはいけません。

さらに、それはおそらくThread Bまだ実行中であることを意味します。しかし、JVMが言おうとしているのは、「危険です!危険です!待っていたものを待つのをやめて、実行してください!」です。

于 2012-07-19T17:07:53.523 に答える
2

このような場合、例外を処理する適切な方法は何ですか?

現在のスレッドを取得するたびに、InterruptedExceptionそれ自体が中断されたと見なす必要があります。通常、これは、スレッドがそれ自体の後にクリーンアップして終了する必要があることを意味します。あなたの場合、メインスレッドは別のスレッドによって中断されており、おそらくThread aそれが開始したスレッドを中断してから終了する必要があります。

割り込みを無視するかどうかはあなた次第ですが、それは悪い習慣であることをお勧めします。割り込みをスレッドへの何らかのシグナルとして使用している場合は、代わりにvolatile booleanフラグを設定します。

をキャッチするときのベストプラクティスに関してはInterruptedException、通常、次のようにします。

try {
    ...
} catch(InterruptedException e){  
    // a good practice to re-enable the interrupt flag on the thread
    Thread.currentThread().interrupt();
    // in your case you probably should interrupt the Thread a in turn
    a.interrupt();
    // quit the thread
    return;
}

をキャッチするInterruptedExceptionとスレッドの割り込みフラグがクリアされるため、catch ブロックで割り込みフラグを再度有効にすることを常にお勧めします。

私が見たさまざまな例では、教科書であっても、例外は無視されます。

それはそう。例外を無視することは非常に悪い習慣ですが、常に発生します。闇の勢力に屈するな!

スレッド B がまだ実際に実行可能/実行中の可能性はありますか?

Thread B確かにまだ実行できます。join()中断されたのは、 を呼び出しているメイン スレッドです。

于 2012-07-19T17:04:18.653 に答える