У меня есть поток, который время от времени обновляет его состояние, и я хочу, чтобы второй поток мог ожидать завершения первого потока.Примерно так:
Thread 1:
while(true) {
...do something...
foo.notifyAll()
...wait for some condition that might never happen...
...
}
Thread 2:
...
foo.wait();
...
Теперь это выглядит красиво и все, если только notifyAll () потока 1 не выполняется до ожидания потока 2), и в этом случае поток 2 ожидает, пока поток 1 не уведомит снова (что может никогда не произойти).
Мои возможные решения:
a) Я мог бы использовать CountDownLatch или Future, но у обоих есть проблема в том, что они по своей сути запускают только один раз .То есть в цикле while потока 1 мне нужно было бы создать новый foo для ожидания каждый раз, а поток 2 должен был бы спросить, какого foo ждать.У меня плохое предчувствие простой записи
while(true) {
foo = new FutureTask();
...
foo.set(...);
...wait for a condition that might never be set...
...
}
, так как я боюсь, что при foo = new FutureTask (), что происходит, когда кто-то ждал старого foo (по «какой-то причине»), set не вызывался,например ошибка в обработке исключений)?
б) Или я мог бы использовать семафор:
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.
Вопрос:
Нет ли в API Java ничего похожего на поведение событий Windows?Или, если вы презираете Windows, что-то вроде WaitGroup golang (то есть CountDownLatch, который позволяет countUp ())?Что-нибудь?
Как сделать это вручную:
Поток 2 не может просто ждать из-за ложного пробуждения, и в Java нет способа узнать, почему Object.wait ()вернулся.Поэтому мне нужна переменная условия, которая хранит, сигнализировано ли событие или нет.Поток 2:
synchronized(foo) {
while(!condition) {
foo.wait();
}
}
И Поток 1, конечно, устанавливает условие в true в синхронизированном блоке.Спасибо Weekens за подсказку!
Существует ли существующий класс, который переносит это поведение?
Или мне нужно скопировать и вставить код повсюду?