2011-10-25 10 views
2

私は、Java Concurrency in Practiceの第7章を読んでいます。Java:コードから割り込み可能なメソッドを呼び出す

独自の取り消しポリシーを持たないが、中断する可能性のあるメソッドを呼び出すメソッドについて説明しているセクションでは、この本は次のように述べています。 中断がdetected.Inこの場合のときのキャンセルをサポートしていますが、まだ中断 遮断する方法は、ループ内でそれらを呼び出す必要があります呼び出すことはありません

活動、再試行は、彼らがローカル 中断の状態を保存し、それを復元する必要があります返される直前に、InterruptedExceptionを捕捉した直後ではなく です。

私はこれを完全に理解していません。

私の方法でThread.sleepを呼び出すと、それをループなどで呼び出す必要がありますか?

誰にもそうする必要がある理由を説明できますか?

+0

合理的な説明があります:http://stackoverflow.com/questions/7751690/noncancelable-task-that-restores-interruption-before-exit – Cole

答えて

4

私は私の方法でのThread.sleepを呼び出す、私はループか何かでそれを呼び出す必要がありますか?

Thread.sleep()は、現在のスレッドが(別のスレッドによって)中断されたときにInterruptedExceptionをスローします。それに対処する方法はあなたの選択です。誰かがあなたを妨害しようとしているかどうかにかかわらず、眠りたい場合は、try-catchブロックの周りにある種のループを構築する必要があります。別のスレッドが中断している場合は、おそらくあなたは、などの例外がスローされる前に、あなたが眠っていたどのくらいの時間をチェックした後、残りの時間のために眠って継続するInterruptedExceptionがスローされていることを

のみをクロック(例えばSystem.nanoTime())を使用する必要があります現在のスレッド、(current)Thread.interrupt()を呼び出すことによって。それ自体では起こるわけではないので、一般的に、睡眠やそれに類するものの周りにループを構築する必要はありません。通常、スレッドは正常な理由(アプリケーションのシャットダウンなど)でのみ中断されるため、特別な理由がない限り、キャンセル/中断をサポートしたいと思うかもしれません。「特別な理由」は、たとえば、I/Oデバイスに書き込むこと、およびキャンセルの試みに関係なく、すべてのデータが書き込まれることを保証しようとすることです。

0

私がこれを理解する限り、中断される可能性のある、または中断されるべきではない長時間実行されるサービスは、中断される可能性のある他のメソッドを呼び出しています。だから、この長年走っているこのサービスは、これを検出して、メソッドやフラグで報告することができます。しかし、InterruptedExceptionを投げるのではなく、操作を再試行することができます。

ブロックを意味するメソッドを呼び出すには、現在の実行がブロックされ、ブロッキングメソッドが値を返すまで待機しています。これはループで行うことができます。メソッド呼び出しが成功したか、呼び出されたメソッドが中断されたかを知っています。

0

私は本を持っていません。しかし、私が理解する限り、アクティビティが中断された場合(スリープは割り込み信号ではありませんが、割り込み信号によってスリープからスレッドを呼び起こすことができます)、アクティビティは現在の動的データ(割り込みステータス)を順番に保存する必要があります以前の状態から復旧します。例えば;

//Let's say you have integer data named "a"... 
a = 45646; 

//Normally after interruption, and terminating the activity data a is currently 
//referencing @memory will be released... 

//If you want to continue using data in a you have to save it somewhere 
// persistant(Let's say a file) 
void onInterruptionDetected() 
{ 
    saveToSomeFile(a, "temp.txt"); 
} 

//After re-execution of activity(Assuming we need a's previous data in order to 
// continue...), we can recover a's data(which is 45646) in previous interruption... 
void onResumeDetected() 
{ 
    a = loadFromFile("temp.txt") 
} 

この情報がお役に立てば幸いですが、私はまだエラーがあるかもしれない眠いよ:)

1

最初のいくつかの説明:スレッドの

割り込みステータスは、基本的にinterrupt()によって「真」に設定されているブールフラグです。 このフラグの現在の状態はとなります。Thread.currentThread().isInterrupted()です。

割り込み操作(のようなObject.wait()またはThread.sleep())は、中断フラグが を設定し、それが(「偽」に設定されている)、このようになりますフラグ、InterruptedExceptionと同時に明確をスローします発見した場合:

if (Thread.interrupted()) { throw new InterruptedException(); } 

Thread.interrupted()は、中断されたフラグを暗黙的にクリアすることに注意してください。 これは、catch(InterruptedException ie) {...}が実行されるまでに、 スレッド自体がそれが中断されたことを知らないことを意味します。

まずキャンセルをサポートするタスクの例:の2つの例を見てみましょう、と述べた

。ここで 、私たちは本当にどこまで作業が進行中止される前に気にしない:このコードは=それが中断されていない場合、それが完了しますと、出力の」x 0から10までのxをカウントしようとし

public void run() { 

    int x = 0; 

    try { 

     while (x < 10) { 
     Thread.sleep(1000); // Some interruptible operation 
     x++; 
     } 

     System.out.println("x = " + x); 

    } catch (InterruptedException ie) { 

     System.out.println("Interrupted: x = " + x); 

     // We know we've been interrupted. 
     // Let the caller know it, too: 
     Thread.currentThread().interrupt(); 
    } 

    } 

10 "となる。 しかし、スレッドが中間で中断された場合は、InterruptedExceptionがスローされ、xをインクリメントする処理が中断されます。 この場合、出力は、スレッドが中断されたときに応じて、「中断:x = 0」から「中断:x = 9」のいずれかになることがあります。

以降に終了する前にスレッドの割り込みフラグを復元することをお勧めします。そうしないと、中断されたステータスはこのrun()メソッドの呼び出し元には表示されません。

public void run() { 
    int x = 0; 

    boolean wasInterrupted = false; // <- This is the local variable to store the interruption status 

    while (x < 10) { 

     wasInterrupted = wasInterrupted || Thread.interrupted(); // not really needed in this case, but for the sake of completeness... 

     try { 

     Thread.sleep(1000); // <- Some interruptible operation 

     } catch (InterruptedException e) { 
     wasInterrupted = true; 
     } 

     x++; 
    } 

    System.out.println("x = " + x); 

    if (wasInterrupted) { 
     Thread.currentThread().interrupt(); 
    } 

    } 
:それは、出力は常にキャンセルをサポートしていないタスクを意味し、「X = 10」、になるように私たちのタスクは、完全な形で実行することが重要である場合

は今、私たちは別のアプローチが必要

この場合、タスクが完了するまでInterruptedExceptionの後でも処理を続行します。 割り込みを検出すると、その状態をwasInterruptedに保存して、 がメソッドから戻る前に割り込みフラグを正しく設定できるようにします。ローカルに中断状態を保存し、ちょうど返す前にそれを復元する必要があり

が何を意味するかだ

それは言う私たちは厳密に中断をこのように処理するために必要とされていないので、「すべきである」 - 私たちは同様にただのInterruptedException を無視し、私たちのタスクを完了することがあり、その後、戻ります。ただし、これは上記の優れた方法ではなく、一部のシナリオで問題を引き起こす可能性があります。

関連する問題