2016-06-01 2 views
0
public static void main(String[] args) { 
    Thread thread = new Thread(new Runnable() { 
     public void run() { 
      try { 
       Thread.sleep(99999); 
      } 
      catch(InterruptedException e) { 
       System.out.println("I'm interrupted!!"); 
      } 
     } 
    }); 

    thread.start(); 
    out.print(thread.isAlive()+" "); 
    thread.interrupt(); 
    out.print(thread.isAlive()+" "); 
} 

コンソールは、私は中断してる真真トラブル()メソッド

である理由を私は理解していません!

が、私は結果は私が中断してい

本当だと思います!! true

なぜ私は思っていますか?ありがとう!

+0

スレッドは、同期されていないときはいつでも「並列」で実行されます。 「並行」とは、物事が異なるスレッドで発生する順序についての保証がないことを意味します。あなたの2番目のスレッドは、最初のスレッドが割り込みを行う前に "中断されました"というメッセージを出力することはできません - これは同期の例です - しかし、あなたのプログラムはprintln()呼び出しを許可し、平行_。すなわち、これらの事柄のどれが最初に起こるかの保証はありません。 –

答えて

2

TL; DR:Thread#interrupt()方法はすぐにInterruptedException例外を必要としないが、それは単にtrueに割り込みステータスという内部フラグを設定し、この1は、影響を受けたスレッドによって確認されています。

割り込みメカニズムは、割り込みステータスとして という内部フラグを使用して実装されます。 Thread.interruptを呼び出すと、このフラグが設定されます。 スレッドが静的メソッド Thread.interruptedを呼び出して割り込みをチェックすると、割り込みステータスはクリアされます。非アクティブな Thread.isInterruptedは、1つのスレッドが別のスレッドの割り込みステータスを照会するために使用し、割り込みステータスを フラグに変更しません。

だから、割り込みステータスのセット、そしてあなたがThread.isAlive()への呼び出しの両方の後に印刷I'm interrupted!!が発生した理由を説明するInterruptedExceptionの投げ、間にいくつかの最小限の遅延を発生します。

+0

あなたの答えをありがとう! –

+0

あなたは大歓迎です;) – Mik378

+0

私はあなたが新しいと思うので、その答えがあなたを助けてくれたと思うなら、それを検証するかもしれません;) – Mik378

1

タイミングの問題です。

threadが実際に終了する前にメインスレッドが続行し、thread.isAlive()を印刷すると、trueが印刷されます。 2番目の出力にブレークポイントを置き、プログラムを続行する前にしばらく待つことでこれを簡単に確認できます。 2番目のisAliveのチェックにはfalseが印刷されます。

おそらく、あなたのプログラムの出力は、主スレッドと他のスレッドとの間で行われたコンテキストスイッチに応じて時々異なるでしょう。

実際には、スレッドのステータスを照会する瞬間に、2番目のスレッドが既にスリープ状態になっていることを確認することさえできません。スレッドの実行順序を互いに依存させたい場合は、スレッド間の同期を導入する必要があります。

+0

2番目の出力にブレークポイントを設定しました。あなたの提案をありがとう。 –