我有一个线程会不时地更新它的状态,我想让第二个线程能够等待第一个线程完成。就像这样:
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(); } }
}
但我担心存在一些竞争条件,如果多个线程在另一个线程signal()和reset()的同时等待它。
问题:
Java API中是否没有类似于Windows事件行为的东西?或者,如果您不喜欢Windows,则类似于golang的WaitGroup(即允许countUp()的CountDownLatch)?任何东西吗?
如何手动完成:
由于虚假唤醒,Thread 2不能简单地等待,在Java中没有办法知道为什么Object.wait()返回。因此,我需要一个条件变量来存储事件是否已被信号化。Thread 2:
synchronized(foo) {
while(!condition) {
foo.wait();
}
}
当然,线程1在同步块中将条件设置为 true。感谢 weekens 的提示!
是否有现有的类可以包装这种行为?
还是我需要到处复制和粘贴代码?