gpt4 book ai didi

java - 计数器更改时通知线程

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:14:42 25 4
gpt4 key购买 nike

我正在尝试为自己设计一个类作为 Code Kata,它具有可以设置的值属性,并且该类可以发出 ValueListener 实例。这个想法是有一个 ValueHolder 实例,许多客户端线程同时访问它。每个客户端线程都请求了一个 ValueWatcher 并调用了 waitForValue()。

我真正纠结的是我应该在 wait() 周围的 while 循环中使用什么条件来避免虚假通知(即值没有改变)。我可以看到这种设计可能会使 ValueWatcher 实例错过更新,但现阶段我不太担心。

如果能提供任何指导,我们将不胜感激!

public class ValueHolder {

private int value = 0;
private final Object monitor = new Object();

public void setValue(int value) {
synchronized(monitor) {
this.value = value;
monitor.notifyAll();
}
}

ValueWatcher createChangeWatcher() {
return new ValueWatcher();
}

private class ValueWatcher {
public int waitForValue() {
synchronized(monitor) {
while (==== ??? =====) {
monitor.wait();
return value;
}
}
}
}
}

最佳答案

有趣的问题。这是我想到的一个解决方案。具有版本号以及正在更改的值。每当更新值时,版本号也会增加,这样 ValueWatcher 对象就可以检查版本是否上升意味着发生了变化。

编辑:我最初有一个 AtomicLong 但我从 @John Vint 那里窃取了包装对象的想法。

private final VersionValue versionValue = new VersionValue();

public void setValue(int value) {
synchronized (monitor) {
versionValue.value = value;
versionValue.version++;
monitor.notifyAll();
}
}

private class ValueWatcher {
private long localVersion = 0;
public int waitForValue() {
synchronized (monitor) {
while (true) {
if (localVersion < versionValue.version) {
// NOTE: the value might have been set twice here
localVersion = versionValue.version;
return versionValue.value;
}
monitor.wait();
}
}
}
}

private static class VersionValue {
int value;
long version;
}

此外,尽管虚假唤醒是可能的,但请务必记住以下文本:

Always invoke wait inside a loop that tests for the condition being waited for. Don't assume that the interrupt was for the particular condition you were waiting for, or that the condition is still true.

更多的是关于竞争条件和生产者/消费者模型,而不是虚假唤醒。参见 my page here about that .

关于java - 计数器更改时通知线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9592992/

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