Java Reference
In-Depth Information
QUICK SUMMARY
1. Avoiding contention for synchronized objects is a useful way to mitigate their per-
formance impact.
2. Thread-local variables are never subject to contention; they are ideal for holding
synchronized objects that don't actually need to be shared between threads.
3. CAS-based utilities are a way to avoid traditional synchronization for objects that
do need to be shared.
False Sharing
One little-discussed performance implication of synchronization involves false sharing. That
used to be a fairly obscure artifact of threaded programs, but as multicore machines become
the norm—and as other, more obvious, synchronization performance issues are ad-
dressed—false sharing is an increasingly important issue.
False sharing occurs because of the way in which CPUs handle their cache. Consider the data
in this simple class:
public
public class
class DataHolder
DataHolder {
public
public volatile
volatile long
long l1 ;
public
public volatile
volatile long
long l2 ;
public
public volatile
volatile long
long l3 ;
public
public volatile
volatile long
long l4 ;
}
Each of the long values here is stored in memory adjacent to one another; for example, l1
could be stored at memory location 0xF20. Then l2 would be stored in memory at 0xF28, l3
at 0xF2C, and so on. When it comes time for the program to operate on l2 , it will load a rel-
atively large amount of memory—for example, 128 bytes from location 0xF00 to
0xF80—into a cache line on one of the cores of (one of) the CPU(s). A second thread that
wants to operate on l3 will load that same chunk of memory into a cache line on a different
core.
Loading nearby values like that makes sense in most cases: if the application accesses one
particular instance variable in an object, it is likely to access nearby instance variables. If
Search WWH ::




Custom Search