Using compound operators as well as increments and decrements (and toggling, in the case of boolean
s) on primitive fields are not
atomic operations. That is, they don’t happen in a single step. For instance, when a volatile
primitive field is incremented or
decremented you run the risk of data loss if threads interleave in the steps of the update. Instead, use a guaranteed-atomic class such as
AtomicInteger
, or synchronize the access.
Noncompliant Code Example
private volatile int count = 0;
private volatile boolean boo = false;
public void incrementCount() {
count++; // Noncompliant
}
public void toggleBoo(){
boo = !boo; // Noncompliant
}
Compliant Solution
private AtomicInteger count = 0;
private boolean boo = false;
public void incrementCount() {
count.incrementAndGet();
}
public synchronized void toggleBoo() {
boo = !boo;
}
See
- CERT, VNA02-J. - Ensure that compound operations on shared variables are atomic