Ожидание события на Java - насколько это сложно?

У меня есть поток, который время от времени обновляет свое состояние, и я хочу, чтобы второй поток мог ждать, пока первый поток быть сделано. Примерно так:

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 за подсказку!

Есть ли существующий класс, который обертывает это поведение?

Или мне нужно скопировать и вставить код повсюду?

16
задан Kosta 19 December 2011 в 14:09
поделиться