I am trying to design a class as a Code Kata for myself that has a value property that can be set, and the class can issue ValueListener instances. The idea is that there is one instance of ValueHolder with many client threads accessing it concurrently. Each client thread has requested a ValueWatcher and has called waitForValue().
What I am really struggling with is what condition I should use on the while loop around the wait() to avoid spurious notifications (i.e. value hasn’t changed). I can see that this design may make it possible of ValueWatcher instances to miss updates, but am less worried about that at this stage.
Would appreciate any guidance on offer!
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;
}
}
}
}
}
Interesting problem. Here’s one solution off the top of my head. Have a version number along with the value that is being changed. Whenever the value is updated, the version number is also incremented so the
ValueWatcherobjects can then check to see if the version went up meaning a change has happened.Edit:
I initially had an
AtomicLongbut I am stealing the idea of a wrapper object from @John Vint.Also, although spurious wakeups are possible it is important to remember that the text:
Is more about race conditions and producer/consumer models than spurious wakeups. See my page here about that.