いくつかのことを行うスレッドがあります。そのうちの1つは、しばらく寝ることです。通常のスリープの後、delayFinished()
メソッドを呼び出しますが、スリープが中断された場合は呼び出すdelayFinished()
べきではありません。また、他のスレッドから呼び出される可能性のあるスリープを中止するメソッドも必要です。
これは私の意図を捉えた実装ですが、うまくいかないと思います:
public class MyThread extends Thread {
private boolean sleeping=false;
private Object sleepingControl=new Object();
//... other unrelated stuff...
private void delay() {
try {
synchronized(sleepingControl) {
sleeping=true;
sleep(delay);
sleeping=false;
delayFinished();
}
} catch (InterruptedException e) {
sleeping=false;
}
}
public void abortDelay() {
synchronized(sleepingControl) {
if (sleeping)
interrupt();
}
}
}
delay()
が呼び出され、スリープ中にabortDelay()
別のスレッドによって呼び出された場合 (主な使用例)、の呼び出し元がそのモニターを所有し、まだ放棄していないためabortDelay()
、同期ステートメントでハングします。delay()
一方、遅延がこのように実装されている場合:
private void delay() {
synchronized(sleepingControl) {
sleeping=true;
}
try {
sleep(delay);
delay()
が呼び出され、同期ブロックのスリープ設定を true に終了する可能性がありますが、その後呼び出され、
スレッドがまだスリープを開始していなくてもabortDelay()
呼び出されます。interrupt()
これらの試みの改善を提案できる人はいますか?