2009-06-21 3 views
30

私はホビープロジェクトでjava.util.concurrent.Semaphoreを使用しています。私が書いている接続プールクラスで使われています。自分で何かを中断しないとInterruptedExceptionsについて心配する必要はありますか?

私は InterruptedExceptionを処理するために強制的に
public void acquire(int permits) throws InterruptedException 

:私はこの方法を除いて、少しの手間でそれを使用することができます。今、私はスレッドの「中断」が何を意味しているのか分かりませんし、コード内で明示的にも明示的でもありません。私は例外を無視することができますか?私はそれをどのように扱うべきですか?

答えて

1

Thread.interrupt()を呼び出してスレッドを中断することができます。これは、何か他のことを行うはずのスレッドを正常に通知するために使用されます。通常は、ブロッキング操作(Thread.sleep()など)が先に返され、InterruptedExceptionがスローされます。スレッドが中断されると、フラグがセットされます。このフラグは、Thread.isInterrupted()呼び出しによって照会できます。

スレッド中断を使用せずにこの例外が発生した場合は、スレッドを終了して(例外を記録することをお勧めします)。

通常は、マルチスレッドアプリケーションの機能によって異なります。

0

スレッドで必要なクリーンアップを実行した後で、run()メソッドを終了する必要があります。
HTH

6

Nope。 InterruptedExceptionは、スレッドを自分で中断した場合にのみ生成されます。あなた自身がThread.interrupt()を使用しない場合、私はそれを何らかの「予期しない例外」として再スローするか、エラーとしてログに記録して移動します。私はInterruptedExceptionをキャッチし、私はinterrupt()自分自身を呼び出すことはありませんことを強制していたときに私のコードではたとえば、私はそれが予想外の場合だ

catch (InterruptedException exception) { 
    throw new RuntimeException("Unexpected interrupt", exception); 
} 

の同等の操作を行います。意図的に私のスレッドを中断する場所がたくさんあります。その場合、私はInterruptedExceptionをよく定義された方法で処理します。通常は、私が入っているループを終了し、クリーンアップしてからスレッドを停止します。

1

例外:InterruptedExceptionをスローすると、あなたが方法でそれを宣言し、私が提案する方法でそれを処理する方法がわからない(そしてそれは、発信者など)、それは何か、あなたが発生することが予想されることはありません場合は

私はそれをキャッチしたい場合AssertionErrorでラップします。

27

はい、あなたはへの必要性は、あなたが投げるか、処理しなければならないのいずれか、他の確認済みの例外のために心配する必要はあり同じように、およそInterruptedException心配します。

ほとんどの場合、InterruptedExceptionは、停止要求を示しています。ほとんどの場合、コードを実行していたスレッドがinterruptedであったためです。

接続プールが接続を待っている特定の状況では、これはキャンセルの問題であり、取得を中止して中断したフラグを復元する必要があります(下記参照)。一例として、


あなたはExecutor内で実行されているRunnable/Callableのいくつかの並べ替えを使用している場合、あなたは正しく例外:InterruptedExceptionを処理する必要があります。

executor.execute(new Runnable() { 

    public void run() { 
     while (true) { 
       try { 
       Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        continue; //blah 
       } 
       pingRemoteServer(); 
     } 
    } 
}); 

これは、あなたのタスクは従うことがないことを意味しますエグゼキュータによって使用される割り込みメカニズムであり、適切なキャンセル/シャットダウンを許可しません。

代わりに、適切なイディオムが中断状態を復元してから、実行を停止することです:

executor.execute(new Runnable() { 

    public void run() { 
     while (true) { 
       try { 
       Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        Thread.currentThread().interrupt(); // restore interrupted status 
        break; 
       } 
       pingRemoteServer(); 
     } 
    } 
}); 

便利なリソース

+3

もちろんです。詳細については、Java専門家のニュースレターhttp://www.javaspecialists.co.za/archive/Issue056.html –

+1

Thread.currentThread()。Thread.interrupted()ではなくinterrupt()にする必要はありませんか? javadocsによると、Thread.interrupted()は割り込みフラグをクリアし、設定しません。 –

+0

@Joe:そうです、私は例を修正しました。ありがとうございました。 –

関連する問題