У меня есть нить, которая делает несколько вещей. Один из них - просто спать в течение некоторого времени. После нормального сна он вызывает метод delayFinished()
, но если спящий прерван, то delayFinished()
не следует вызывать. Мне также нужен метод, который прерывает сон, который может быть вызван другими потоками.Pure Java: Как узнать, спал ли мой поток или нет?
Так это реализация, которая захватывает мое намерение, но я не думаю, что это будет работать:
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()
называется, заканчивает синхронизированный блок настройки сна, чтобы верно, но тогда abortDelay()
называется, и было бы назвать interrupt()
, хотя нить еще не начала спать.
Может ли кто-нибудь предложить какие-либо улучшения этих попыток?
Действительно ли это «синхронизированный» материал? –
'wait() имеет любопытную реализацию quirk, где он может ложно просыпаться »- я подозреваю, что только на ОС с примитивами синхронизации, которые работают неправильно. –
Если вы вызываете delay() более одного раза (из любого места внутри класса), может возникнуть проблема с пониманием того, какой из вызовов должен быть прерван с помощью метода abortDelay() –