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