スレッドで待機し、別のスレッドで解放できる Java の Mutex が必要です。容量が 1 のセマフォを使用できることはわかっていますが、問題は「acquire()」メソッドが「InterruptedException」をスローすることです。Javaでこの目的のための特別な同期方法はありますか?
4 に答える
幸いなことに、セマフォはこのメソッドを提供しています:)
public void acquireUninterruptably()
このセマフォからパーミットを取得し、使用可能になるまでブロックします。パーミットが利用可能な場合は取得し、すぐに返して、利用可能なパーミットの数を 1 つ減らします。
利用可能な許可がない場合、現在のスレッドはスレッド スケジューリングの目的で無効になり、他のスレッドがこのセマフォの release() メソッドを呼び出し、現在のスレッドに次に許可が割り当てられるまで休止状態になります。
パーミットを待っている間に現在のスレッドが中断された場合、スレッドは引き続き待機しますが、スレッドにパーミットが割り当てられる時間は、中断が発生しなかった場合にパーミットを受け取った時間と比較して変化する可能性があります。スレッドがこのメソッドから戻ると、その割り込みステータスが設定されます。
InterruptedException
は問題ではありません。ループでラップするだけです。
while(true) {
try {
semaphore.acquire();
break;
} catch(InterruptedException e) {
//swallow, continue;
}
}
ただし、このコードはあまり安全でも洗練されたものでもありませんが、「確実に許可を取得したい!」場合には機能します。
スレッドが待機するコードがある場合は、同期ブロックを使用していない限り、割り込み例外を確実に処理する必要があります。また、中断された例外の問題は何ですか?
スレッドA
volatile boolean waitCondition = true
synchronized(lockObject) {
while (waitContidion) {
lockObject.wait();
}
}
スレッドB
synchronized(lockObject) {
waitCondition = false;
lockObject.notifyAll();
}
または、Lock インスタンスで Condition/Signal を使用します。
InterruptedException の正しい処理は非常に重要です。少なくとも、catch ブロックのThread.currentThread().interrupt()メソッドで中断フラグを設定する必要があります。