I am a novice when it comes to concurrency and unsure of myself when spotting issues, I was looking through a fairly established code base and found the following code (edited for brevity) which I believe to be susceptible to data races:
public class Example extends Thread {
boolean condition = false;
public void run () {
while (true) {
synchronized (this) {
try {
while( condition ) wait();
}
catch (InterruptedException e) { /*for brevity*/ }
}
// non-blocking computation
}
}
public void setTrue () { condition = true; }
public void setFalse () {
synchronized (this) {
condition = false;
this.notifyAll();
}
}
}
As far as I understand condition
must be volatile since even with the synchronized block, the compiler will not issue any memory barriers; if it were a volatile store to condition
in setTrue
the compiler would issue StoreEnter.
Am I right to believe the above is susceptible to data races? And if so how can I witness the data race through an example (as opposed to simply knowing the guarantees provided by the JMM). A simple test with threads randomly invoking setTrue
in a loop doesn't uncover the data race.
Also, I believe the use of notifyAll is overkill here since there is one condition to check and only one thread will ever be waiting on it, right?
Thank you.