5

java.util.concurrent.ConcurrentHashMap uses a Segment array as Mutexand Segment Object is small than cache line.

Does this lead to false sharing?

Thomas Shields
  • 8,874
  • 5
  • 42
  • 77

2 Answers2

4

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:

  1. The new implementation is less susceptible to false sharing, because you'd expect different threads to hit the same Node only if there are bucket collisions.
  2. The @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.
Dimitar Dimitrov
  • 16,032
  • 5
  • 53
  • 55
  • Thanks a lot for your answer and the tools you recommended which help me a lot.I noticed that long fields named `xxxOffset` is static,it seems belong to `AbstractQueuedSynchronizer` class not the `Sync` Object. –  Mar 25 '16 at 06:35
2

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.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130