State of parallel race?

This class extends Thread , and as soon as it is created, the thread starts. This is the code:

 class Controller extends Thread implements ConfigurationObserver{ private int refreshMS; //... @Override public void notifyConfiguration(ConfigurationModel config) { refreshMS = config.getRefreshMs(); } @Override public void run() { //... while (true) { try { Thread.sleep(refreshMS); } catch (InterruptedException ex) { //... } } } } 

This follows the observation pattern . This class will subscribe to the ConfigurationController , which will notify it every time when any of the configuration parameters are changed using the notifyConfiguration(...) method.

What makes me a little unsure of this is the refresMS attribute. The configuration is changed through the graphical interface (Thread # 1) and affects the attribute of the Controller class (Thread # 2), which is read from the current thread of this class (Thread # 3).

Q1: Could this be a condition of the race?
Q2: If so, what is the best way to solve this problem?

+4
source share
2 answers

The solution I made is the one proposed by pingw33n. Using the volatile keyword.

 class Controller extends Thread implements ConfigurationObserver{ private volatile int refreshMS; //... } 

Quote from Brian Goetz Volatility Management

Volatile variables share the visibility functions of a synchronized, but not one of the features of atomicity. This means that threads will automatically see the most current value for volatile variables.

This means that volatile can be used instead of synchronized in very few cases. But, fortunately, this is one of them, since int is typed atomically (a thread cannot read its value, and the other modifies it).

Therefore, as Stephen S said, this does not eliminate the state of the race, it only makes it a truly rare case. In my case, if refresMS read with the old value by the working thread, it doesn't matter much (if it's something that barely happens).

+2
source

Q1: Could this be a condition of the race?

Yes. Like. The run() method may end up using the refreshMS value, which is deprecated.

Q2: If so, what is the best way to solve this problem?

This minimizes the race condition:

 class Controller extends Thread implements ConfigurationObserver{ private int refreshMS; public synchronized void notifyConfiguration(ConfigurationModel config) { refreshMS = config.getRefreshMs(); } public void run() { while (true) { ... synchronized (this) { rms = refreshMS; } Thread.sleep(rms); .... } } } 

You cannot completely rule out a race condition without making a sleep call inside a synchronized block. (This will trigger a thread that calls notifyConfiguration to block for a potentially unlimited period of time. Bad idea.)


Now everything is fine and good, but you should also ask yourself if the race condition can adversely affect the execution of the application.

+3
source

All Articles