2012-08-28 1 views
9

一見簡単な問題:java.util.concurrent.Semaphoreがあり、acquire()を使用して許可証を取得したいと考えています。Semaphore.acquire()は偽のウェイクアップのためにInterruptedExceptionをスローできますか?

acquire()メソッドは、スレッドが中断された場合InterruptedExceptionをスローするように指定されている:

現在のスレッド場合:

  • は、このメソッドへのエントリ上で設定された割り込みステータスを持っています。または許可を待っている間に
  • が中断され、

は、InterruptedExceptionがスローされ、現在のスレッドの割り込みステータスはクリアされます。

スレッドが中断されていると同じように見える偽のウェイクアップの対象とすることができるのでしかし、InterruptedExceptionを投げることの方法といつものパターンは、ループ内でそれらを呼び出すことです。例えば、documentation for Object.wait(long)は言う:

スレッドがも通知、中断された、またはタイムアウト、いわゆるスプリアスウェイクアップされずに目を覚ますことができます。これは実際にはめったに発生しませんが、アプリケーションはスレッドを起動させるはずの状態をテストし、条件が満たされない場合は待機し続けます。言い換えれば、ループ内で常に待機する必要があります。

したがって、同じ種類の疑似ウェークアップの対象となるのは、Semaphore.acquire()ですか?論理的な答えは「いいえ」ですが、私はその証拠を見つけることができず、実際に証拠は他の方向を指すようです。

source for Semaphoreを見ると、それが表示されること委譲LockSupport.park()its source委譲によるAbstractQueuedSynchronizerに実際の取得、。

documentation for LockSupport.park()が明示的に見せかけの起動に言及したが、AbstractQueuedSynchronizer.doAcquireInterruptably()の実装はちょうどThread.interrupted()をチェックしてからInterruptedExceptionをスローするように表示されます。

私は(非常に可能性がある)何かが欠けていない限り、Semaphore.acquire()誤っInterruptedExceptionを投げることができるように見えますか?

これは間違いありませんか?もっと重要なのは、それについて私ができることは何か?私はSemaphore.acquireUninterruptably()を使用することができましたが、私は中断されない待機を望んでいません。何か別の選択肢はありますか?

+2

"スプリアス割り込み"ではなく、 "スレッドは通知、中断、またはタイムアウトすることなく起きることもあります。いわゆる擬似ウェイクアップ"です。偽の起床中にスローされたInterruptedExceptionはありません。 –

+0

@SkipHead:スレッドは起きますが、 'interrupted'フラグはセットされていませんか?それは理にかなっています - それを答えとして投稿できますか? –

答えて

7

「スプリアス割り込み」ではない:「スレッドは、通知、中断、またはタイムアウトを起こすことなく起きることもあり、いわゆる擬似ウェイクアップ」。偽の起床中にスローされたInterruptedExceptionはありません。コメントで言うとおり:スレッドは起動しますが、中断されたフラグは設定されません。

2

Semaphore.acquire() APIについて考えてみると、主に発信者が「偽」と「通常」を区別する方法がないため、偽のウェイクアップが不可能であることがわかります。方法は役に立たないです。

+0

合意しました。それが私が質問した理由です。私はあまりにも多くを仮定し、私の前提を検証するためにコードをチェックするつもりでしたが、偽のエラーが発生する可能性があるという証拠を見つけたと思われたので、私は不安でした。 –

関連する問題