gpt4 book ai didi

java - 在 Java 中等待一个事件——有多难?

转载 作者:太空狗 更新时间:2023-10-29 22:51:49 25 4
gpt4 key购买 nike

我有一个线程不时更新它的状态,我希望第二个线程能够等待第一个线程完成。像这样:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com