java.util.concurrent.ConcurrentHashMap
uses a Segment
array as Mutex
and Segment Object
is small than cache line.
Does this lead to false sharing?
java.util.concurrent.ConcurrentHashMap
uses a Segment
array as Mutex
and Segment Object
is small than cache line.
Does this lead to false sharing?
First, it's good to distinguish between ConcurrentHashMap
in Java 7 and ConcurrentHashMap
in Java 8, because the implementation difference is significant.
ConcurrentHashMap
in Java 7
Peter Lawrey is correct that the Segment
class extends ReentrantLock
which aggregates a specialization of AbstractQueueSynchronizer
. By itself, AbstractQueuedSynchronizer
contains enough long
fields to pad up to the usually padded length of a cache line (64 bytes). If you do the math, it may turn out that Segment
actually takes 1 cache line + a little bit, so you may argue that it is susceptible to false sharing.
Java Object Layout and Intel VTune should be able to help you figure this out.
ConcurrentHashMap
in Java 8
In Java 8, ConcurrentHashMap
is no longer relying on striped locking. Instead it's using a mostly lock-free algorithm that works on the granularity level of a bucket (called Node
in the new implementation), not of a group of buckets (called Segment
in the old implementation). If you dive into the implementation details, you'll notice that:
Node
only if there are bucket collisions.@Contended
annotation is used in the internal implementation of Java 8's ConcurrentHashMap
, so Doug Lea and the other folks that worked on it indeed have been thinking about false sharing. It's used exactly where you'd expect false sharing to hit the hardest - when you're trying to keep track of the size of the table.While the Segments are small, this is not where the multi-threading support happens. It extends ReentrantLock which uses a Sync object which extends AbstractQueuedSchronizer which uses Node objects. All these objects would be copied as a group and are likely to be spaced out reasonably well. This would depend on the implementation of the GC as to how this is done, but for Hotspot it is copied in reverse order of discovery (i.e. a deep copy) so it is likely this will be fine.