在Java中等待事件 - 这有多难?
我有一个线程会不时更新其状态,我希望第二个线程能够等待第一个线程完成。像这样:
Thread 1:
while(true) {
...do something...
foo.notifyAll()
...wait for some condition that might never happen...
...
}
Thread 2:
...
foo.wait();
...
现在这看起来不错,除非线程 1 的 notifyAll() 在线程 2 的 wait() 之前运行,在这种情况下,线程 2 会等到线程 1 再次发出通知(这可能永远不会发生)。
我可能的解决方案:
a)我可以使用CountDownLatch或Future,但两者都有一个问题,即它们本质上只运行一次。也就是说,在线程 1 的 while 循环中,我需要创建一个新的 foo 来等待每次,而线程 2 需要询问要等待哪个 foo。我对简单地写作有一种不好的感觉
while(true) {
foo = new FutureTask();
...
foo.set(...);
...wait for a condition that might never be set...
...
}
由于我担心在foo = new FutureTask(),当有人等待旧的foo时会发生什么(由于“某种原因”,设置未被调用,例如异常处理中的错误)?
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(); } }
}
但是我担心存在一些争用条件,如果多个线程正在等待()ing,而另一个线程发出信号并重置()s。
问题:
Java API 中是否有任何内容与 Windows 事件行为相似?或者,如果你鄙视Windows,比如golang的WaitGroup(即允许countUp()的CountDownLatch)?什么?
如何手动操作:
线程 2 不能简单地等待,因为虚假唤醒,在 Java 中,没有办法知道为什么 Object.wait() 返回。因此,我需要一个条件变量来存储事件是否发出信号。线程 2:
synchronized(foo) {
while(!condition) {
foo.wait();
}
}
当然,线程 1 在同步块中将条件设置为 true。感谢weekens的提示!
是否有包装该行为的现有类?
还是我需要将代码全部复制并粘贴到所有位置?