- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个线程不时更新它的状态,我希望第二个线程能够等待第一个线程完成。像这样:
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 时会发生什么(由于“某种原因”,没有调用 set,例如异常处理中的错误)?
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(); } }
}
但我担心如果多个线程正在等待它而另一个信号()和重置()则存在一些竞争条件。
问题:
Java API 中是否没有任何类似于 Windows 事件行为的内容?或者,如果你鄙视 Windows,像 golang 的 WaitGroup 这样的东西(即允许 countUp() 的 CountDownLatch)?有什么事吗?
如何手动完成:
由于虚假唤醒,线程 2 不能简单地等待,并且在 Java 中没有办法知道 Object.wait() 返回的原因。所以我需要一个条件变量来存储事件是否发出信号。线程 2:
synchronized(foo) {
while(!condition) {
foo.wait();
}
}
当然,线程 1 在同步块(synchronized block)中将条件设置为真。感谢周末的提示!
是否存在包装该行为的现有类?
还是我需要复制并粘贴所有代码?
最佳答案
标准做法是在执行 notifyAll 时更改某些状态并在执行 wait() 时检查某些状态。
例如
boolean ready = false;
// thread 1
synchronized(lock) {
ready = true;
lock.notifyAll();
}
// thread 2
synchronized(lock) {
while(!ready)
lock.wait();
}
使用这种方法,线程 1 或线程 2 先获取锁并不重要。
如果您使用 notify 或 wait 时没有设置值或检查值,一些编码分析工具会给您警告。
关于java - 在 Java 中等待一个事件——有多难?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8562227/
我是一名优秀的程序员,十分优秀!