2011-10-13 12 views
3

私はいくつかのJavaスレッド中断を読んでいましたが、私はいくつかのことを理解していません。誰かが私を説明してくれることを願ってキャンセルをサポートするが、それでも 割り込み可能ブロッキングメソッドを呼び出すことはありません終了前に中断を復元する取り消し不能なタスク

活動は、ループにそれらを呼び出すする必要があります:だから、それは次のコード

public Integer getInteger(BlockingQueue<Integer> queue) { 
    boolean interrupted = false; 
    try { 
     while (true) { 
      try { 
       return queue.take(); 
      } catch (InterruptedException e) { 
       interrupted = true; 
       // fall through and retry 
      } 
     } 
    } finally { 
     if (interrupted) 
      Thread.currentThread().interrupt(); 
    } 
} 

次のように説明があるが行われています 割り込みが検出されたときに再試行します。この場合、リストに示されているように、 をローカルに中断状態に保存し、戻す直前に復元する必要があります( )。 catchする直後ではなく、 InterruptedExceptionです。ほとんどの割り込み可能なブロッキング メソッドは、エントリの割り込みステータスをチェックし、 InterruptedExceptionが設定されていれば直ちにスローするので、中断されたステータスを早期に設定すると、無限ループになります。 (可能な限り中断するように応答するように割り込み可能な方法は 通常、ブロックまたは重大な 作業を行う前に、割り込みをポーリング。)

我々はローカルに中断された状態を保存しなければならない理由を私は理解していません。
私はいくつかの説明を聞いてうれしいです。

+0

Mmmm。面白い... –

答えて

2

デザインによっては、InterruptedExceptionをスローすることができませんでした。つまり、キューからの価値を常に期待しています。しかし、誰かがスレッドを中断させたいと思うかもしれません。そのため、最終的にキューから値を取得した後、中断した状態を復元する必要があります。

スレッドは、キューから値を取得した後で終了します。

更新:take()メソッドの実装を調べます。これは、最初の文を次のようにあります。

public final void acquireInterruptibly(int arg) throws InterruptedException { 
    if (Thread.interrupted()) 
     throw new InterruptedException(); 
... 
} 
+0

私は誰かがこのメソッドを実行しているスレッドを中断する可能性があることを理解していますが、catchブロックで "Thread.currentThread()。interrupt()"を呼び出さないのはなぜですか? – Bax

+0

"ほとんどの割り込み可能なブロッキングメソッドは、エントリの中断ステータスをチェックし、InterruptedExceptionが設定されていればすぐにスローします。"これはcatchブロックに設定すると、 'take()'メソッドで再びループし、メソッドは(割り込み状態を設定しているため)作業を行う直前に終了することを意味します。 – kan

+0

大丈夫、理解していただきありがとうございます。最後の質問には、finallyブロックに到達するためにはどうなりますか? – Bax

1

ループこれは、それは1のように見えるにもかかわらず、タイトなループではないため、ステートメント

return queue.take(); 

で終了します。 1つの要素をブロックし、利用可能になるとすぐに戻り、中断が発生した場合に再試行します。

+0

最終的に到達したブロックはどのようになりましたか?未知の例外のようなものがあるでしょうか? – Bax

+0

いいえ。finallyブロックは、例外に関係なくtryブロックの終了時に常に実行されます。 – kan

+0

'finally'ブロックは*常に*実行されます - 例外がスローされるかどうかにかかわらず - したがって、上記のコードでは、要素が利用可能な場合、メソッドはfinallyブロックを実行してすぐに戻ります。要素が利用できない場合は、ブロックされます。ブロッキング中にInterruptedExceptionがスローされた場合、それは要素に対してリタイアしますが、* finally *、* all * caseでは、メソッドが戻る前にfinallyブロックが実行されます。 – Bhaskar