Java Reference
In-Depth Information
How It Works
AtomicLong (and its cousin AtomicInteger ) are built to be used safely in con-
current environments. They have methods to atomically increment (and get) the
changed value. Even if hundreds of threads call the AtomicLong increment()
method, the returned value will always be unique.
If you need to make decisions and update the variables, always use the atomic oper-
ations that are offered by AtomicLong ; for example, compareAndSet . If not, your
code will not be thread-safe (as any check-then-act operation needs to be atomic) un-
less you externally protect the atomic reference by using your own locks (see Recipe
10-7).
The following code illustrates several code safety issues to be aware of. First, chan-
ging a long value may be done in two memory write operations (as allowed by the Java
Memory Model), and thus two threads could end up overlapping those two operations
in what might on the surface appear to be thread-safe code. The result would be a com-
pletely unexpected (and likely wrong) long value:
long counter = 0;
public long incrementCounter() {
return counter++;
}
This code also suffers from unsafe publication , which refers to the fact that a vari-
able might be cached locally (in the CPU's internal cache) and might not be committed
to main memory. If another thread (executing in another CPU) happens to be reading
the variable from main memory, that other thread may miss the changes made by the
first thread. The changed value may be cached by the first thread's CPU, and not yet
committed to main memory where the second thread can see it. For safe publication,
you must use the volatile Java modifier (see ht-
tp://download.oracle.com/javase/tutorial/essential/concur-
rency/atomic.html ).
A final issue with the preceding code is that it is not atomic. Even though it looks
like there is only one operation to increment the counter, in reality there are two opera-
tions that occur at the machine-language level (a retrieve of the variable and then an in-
crement). There could be two or more threads that obtain the same value as they both
retrieve the variable but haven't incremented it yet. Then all the threads increment the
counter to the same number.
Search WWH ::




Custom Search