Why is this an issue?
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;
}
Resources
- CERT, VNA02-J. - Ensure that compound operations on shared variables are atomic