You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ConcurrentHashMap默认并发级别为16的原因:为何不设为18?

Why ConcurrentHashMap's Default Concurrency Level is 16 (and Not 18)

Great question—this gets into the practical design tradeoffs that make ConcurrentHashMap work so well for most use cases. Let’s break it down:

Why 16?

  • 2^power optimizes hashing operations: ConcurrentHashMap relies on fast bucket lookups to minimize lock contention. When the number of buckets (or segments, in JDK 1.7) is a power of 2, we can replace the expensive modulo operation (hash % n) with a bitwise AND: hash & (n-1). For 16, that’s hash & 15 (binary 1111), which uses all 4 low bits of the hash value. This ensures more uniform distribution of keys across buckets, reducing collisions and lock fights.
  • Balances concurrency and memory overhead: The default concurrency level represents how many threads can access the map concurrently with minimal contention. 16 strikes a sweet spot—too small (like 4) and you’ll get frequent lock contention in moderately busy systems; too large (like 32) and you waste memory on unused segments/buckets, especially in low-concurrency scenarios. This value was chosen based on real-world performance testing when ConcurrentHashMap was first introduced in JDK 5, aligning with typical hardware and application workloads of the time (and still holds up today).
  • Backward compatibility and convention: Even though JDK 1.8 replaced segments with per-bucket synchronized blocks and CAS operations, the default value of 16 was retained to keep consistency with older codebases and developer expectations.

Why Not 18?

  • Non-power-of-2 breaks efficient hashing: 18 isn’t a power of 2, so we can’t use the fast bitwise AND trick. Instead, we’d have to use hash % 18, which is significantly slower. Worse, 18-1 = 17 (binary 10001), so the bitwise AND would only use the 0th and 4th bits of the hash value. This leads to extremely uneven key distribution—most keys will end up in just a handful of buckets, causing longer chains/trees and way more lock contention.
  • Complicates resizing and memory efficiency: Resizing a map with a non-power-of-2 bucket count requires rehashing every key from scratch, whereas power-of-2 sizes let us just check one additional bit of the hash to decide if a key stays in place or moves to the new bucket. Additionally, memory allocation for arrays works better with power-of-2 sizes (aligning with JVM memory alignment rules), so 18 would introduce unnecessary memory overhead.
  • No meaningful gain: Adding 2 extra "concurrency slots" with 18 gives negligible real-world performance benefits, but the downsides (slower hashing, worse distribution, more complex code) far outweigh any potential upside. There’s no scenario where 18 would be a better default than 16.

内容的提问来源于stack exchange,提问作者Vaithilingam K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:06:04