У меня есть поток, который время от времени обновляет его, и я хочу, чтобы второй поток мог дождаться завершения первого потока. Что-то вроде этого:
Thread 1:
while(true) {
...do something...
foo.notifyAll()
...wait for some condition that might never happen...
...
}
Thread 2:
...
foo.wait();
...
Теперь это выглядит хорошо и все, если Thread 1 notifyAll() не запускается до Thread 2 wait(), и в этом случае Thread 2 ждет, пока Thread 1 не уведомит об этом (что может никогда не произойти).
Мои возможные решения:
a) Я мог бы использовать CountDownLatch или Будущее, но у обоих есть проблема, по которой они по сути работают только один раз. То есть, в Thread 1 while loop, мне нужно будет создать новый foo, чтобы ждать каждый раз, и Thread 2 должен будет спросить, какого foo ждать. У меня плохое представление о простом написании
while(true) {
foo = new FutureTask();
...
foo.set(...);
...wait for a condition that might never be set...
...
}
поскольку я боюсь, что при foo = new FutureTask(), что происходит, когда кто-то ждал старого foo (по какой-то причине, set не был вызван, например, ошибка в обработке исключений)?
b) Или я мог бы использовать семафор:
class Event {
Semaphore sem;
Event() { sem = new Semaphore(1); sem . }
void signal() { sem.release(); }
void reset() { sem.acquire(1); }
void wait() { if (sem.tryAcquire(1)) { sem.release(); } }
}
Но я боюсь, что есть какое-то условие гонки, если несколько потоков ждут() для него, а еще один сигнал() s и reset() s.
Вопрос:
Нет ли в Java API ничего похожего на поведение Windows Event? Или, если вы презираете Windows, что-то вроде golang WaitGroup (т.е. CountDownLatch, который позволяет countUp())? Что-нибудь?
Как это сделать вручную:
Thread 2 не может просто ждать из-за ложного пробуждения и в Java нет способа узнать, почему Object.wait() возвращен. Поэтому мне нужна переменная условия, которая хранит сообщение о событии или нет. Тема 2:
synchronized(foo) {
while(!condition) {
foo.wait();
}
}
И Thread 1, конечно, устанавливает условие true в синхронизированном блоке. Благодаря недельным подсказкам!
Существует ли существующий класс, который обертывает это поведение?
Или мне нужно скопировать и вставить код целиком?