...
Code Block | ||
---|---|---|
| ||
final class ControlledStop implements Runnable { private volatile boolean done = false; public void run() { while (!done) { try { // ... Thread.currentThread().sleep(1000); // Do something } catch(InterruptedException ie) { // handle exception } } } protected void shutdown() { done = true; } } |
Compliant Solution (
...
java.util.concurrent.atomic.AtomicBoolean
)
This compliant solution uses the intrinsic lock of the Class
object an AtomicBoolean
flag to ensure that updates are visible to other threads.
Code Block | ||
---|---|---|
| ||
final class ControlledStop implements Runnable { private booleanAtomicBoolean done = new AtomicBoolean(false); public void run() { while (!isDonedone.get()) { try { // ... Thread.currentThread().sleep(1000); // Do something } catch(InterruptedException ie) { // handle exception } } } protected synchronized boolean isDone() { return done; } protected synchronized void shutdown() { done = true.set(true); } } |
While this is an acceptable compliant solution, it has the following shortcomings as compared to declaring done
as volatile
:
- Performance: The intrinsic locks cause threads to block temporarily;
volatile
incurs no blocking - Deadlock: Excessive synchronization can make the program deadlock prone.
...
Compliant Solution (
...
synchronized
)
This compliant solution uses an AtomicBoolean
flag the intrinsic lock of the Class
object to ensure that updates are visible to other threads.
Code Block | ||
---|---|---|
| ||
final class ControlledStop implements Runnable { private AtomicBooleanboolean done = new AtomicBoolean(false); public void run() { while (!done.getisDone()) { try { // ... Thread.currentThread().sleep(1000); // Do something } catch(InterruptedException ie) { // handle exception } } } protected synchronized boolean isDone() { return done; } protected synchronized void shutdown() { done.set(true) = true; } } |
While this is an acceptable compliant solution, it has the following shortcomings as compared to the previously suggested ones:
- Performance: The intrinsic locks cause threads to block temporarily;
volatile
incurs no blocking - Deadlock: Excessive synchronization can make the program deadlock prone.
However, synchronization is a more secure alternative in situations where the volatile
keyword or an java.util.concurrent.atomic.Atomic*
field is inappropriate, such as if a variable's new value depends on its old value. Refer to CON01-J. Ensure that composite operations on shared variables are atomic for more information.
Risk Assessment
Failing to ensure visibility of shared primitive variables on accesses can lead to a thread seeing stale values of the variables.
...