2011-01-16 4 views
3

古いコードを改訂すると、私は遭遇しました。次のケースで割り込みの代わりにisInterruptedを使用する方が良いでしょう

public void stop() { 
    if (this.simulationThread != null) { 
     this.simulationThread.interrupt(); 

     try { 
      this.simulationThread.join(); 
     } 
     catch (InterruptedException exp) { 
      log.error(null, exp); 
     } 

     this.simulationThread = null; 
    } 
} 

public void run() { 
    while (!Thread.interrupted() && simulationThread == Thread.currentThread()) { 
    } 
} 

私は不思議に思っていました、使用するのが良いでしょうか、それとも重要ではありませんか?

public void run() { 
    Thread t = Thread.currentThread(); 
    // Will it better to use isInterrupted, since it will not clear the interrupt 
    // flag? 
    while (!t.isInterrupted() && simulationThread == t) { 
    } 
} 

答えて

2

これは、run()が終了したときに何が起こるかによって異なります。 run()関数がメインスレッドループである場合、run()が完了するとすぐにそのスレッドを終了させたい場合は、Thread#interrupted()で中断フラグを呑み込んでも問題ありません。

通常、それはあなたがしたいことではありません。 run()機能を正常に終了させて​​協調キャンセルを可能にする場合は、発信者の中断フラグを保持し、ダウンストリームブロッキング機能が検出できるようにすることをお勧めします。そのためには、Thread#isInterrupted()を使用することをお勧めします。あなたがInterruptedExceptionをキャッチあなたのstop()機能で、あなたも再び、それはstop()を呼び出していると何がその後起こることになっていますここに掲載スニペットから明らかではありません

Thread.currentThread().interrupt(); 

を呼び出しますが、必要があることを

注意、 Thread#join()のうちstop()がポップされた中断フラグを保持する方がよいでしょう。ただInterruptedExceptionをキャッチするとstop()はその中断に反応することができますが、呼び出し側または後続のブロック機能は現在のスレッドに対する中断要求を検出できません。言い換えれば、1つのブロッキング関数呼び出しのブロックを解除するだけで、スレッドの割り込みはほとんど満足されません。中断要求は通常が終了するようにスレッドのメイン関数にすべて伝播する必要があります。

最後に、simulationThreadフィールドは揮発性ですか?

関連する問題