public class MyLockConditionTest {
private final Lock alock = new ReentrantLock();
private final Condition condition = alock.newCondition();
private String message = null;
public void waitForCallback() {
alock.lock();
try {
// wait for callback from a remote server
condition.await();
doSomething(message);
} finally {
alock.unlock();
}
}
// another thread will call this method as a callback to wake up the thread called condition.await()
public void onCallbackReceived(String message) {
alock.lock();
try {
this.message = message
condition.signal();
} finally {
alock.unlock();
}
}
}
У меня есть этот код с использованием ReentrantLock и Condition для реализации класса, который будет ждать определенных обратных вызовов с удаленного сервера. Я тестировал этот код и, кажется, работаю, но у меня есть несколько вопросов.Состояние замка Reentrance
Зачем мне нужно делать alock.lock()/unlock() в onCallbackReceived(). Без вызова lock()/unlock() я получал исключение IllegalState. Я запутался, потому что блокировка удерживается вызывающим объектом waitForCallback(), когда onCallbackReceived() вызывается другим потоком, так что alock.lock() в onCallbackReceived() всегда терпит неудачу.
Нужно ли обертывать условие.await() в waitForCallback() с циклом while?
в то время как (сообщение == null) состояние.await();
1) В ожидании состояния требуется мьютекс, чтобы защитить состояние от изменения небезопасными способами (видимость). 2) ложные пробуждения среди других, также https://computing.llnl.gov/tutorials/pthreads/#ConVarSignal для того же самого на низком уровне – zapl