Java Reference
In-Depth Information
Confusing a volatile object with the volatility of its member objects is a similar error
to the one described in
Guideline 73
, “
Never confuse the immutability of a reference with
Noncompliant Code Example (Arrays)
This noncompliant code example declares a volatile reference to an array object:
final class Foo {
private volatile int[] arr = new int[20];
public int getFirst() {
return arr[0];
}
public void setFirst(int n) {
arr[0] = n;
}
// ...
}
Values assigned to an array element by one thread—for example, by calling
setFirst()
—might not be visible to another thread calling
getFirst()
, because the
volatile
keyword guarantees safe publication only for the array reference; it makes no
guarantee regarding the actual data contained within the array.
This problem arises when the thread that calls
setFirst()
and the thread that calls
getFirst()
lack a
happens-before relationship
. A happens-before relationship exists
between a thread that
writes
to a volatile variable and a thread that
subsequently reads
it.
However,
setFirst()
and
getFirst()
each read from a volatile variable—the volatile
reference to the array. Neither method writes to the volatile variable.
Compliant Solution (
AtomicIntegerArray
)
Toensurethatthewritestoarrayelementsareatomicandthattheresultingvaluesarevis-
ible to other threads, this compliant solution uses the
AtomicIntegerArray
class defined
in
java.util.concurrent.atomic
: