如何使用和设置适当的ConcurrentHashMap并发级别?

我正在使用concurrenthashmap中的大约1000个元素。 默认并发级别为16。 任何人都可以帮我一些算法或因素,我可以从中确定适合我的场景的并发级别,或者并发级别以多少方式影响multithreading的处理。

ConcurrentHashMap map=new ConcurrentHashMap(500,1,20); 

20是我的并发级别(虚拟值)。需要有效地设置它

根据文件:

更新操作之间允许的并发性由可选的concurrencyLevel构造函数参数(缺省值16 )引导,该参数用作内部大小调整的提示 。 该表在内部进行分区,以尝试允许指定数量的并发更新而不会发生争用。 因为散列表中的放置基本上是随机的, 所以实际的并发性会有所不同。 理想情况下,您应该选择一个值来容纳与同时修改表一样多的线程。 使用比您需要的更高的值会浪费空间和时间,而显着更低的值可能导致线程争用。

所以你需要回答1个问题:

同时修改表的线程数是多少?

Java 8:

现在, ConcurrentHashMap根本不使用固定的锁定条带方案,而是使用内部同步将每个桶用作“条带”。

源代码:

 /** Implementation for put and putIfAbsent */ final V putVal(K key, V value, boolean onlyIfAbsent) { ... Node f; int n, i, fh; ... else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { ... synchronized (f) { ... } } 

并且构造函数具有参数,只是将其用作文档说明的大小提示。

concurrencyLevel – 并发更新线程的估计数量。 实现可以将此值用作大小提示。

来源:

 public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) { if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) throw new IllegalArgumentException(); if (initialCapacity < concurrencyLevel) // Use at least as many bins initialCapacity = concurrencyLevel; // as estimated threads long size = (long)(1.0 + (long)initialCapacity / loadFactor); int cap = (size >= (long)MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : tableSizeFor((int)size); this.sizeCtl = cap; } 

所以你不需要自己考虑, ConcurrentHashMap会为你处理它。

ConcurrentHashMap允许多个读取器同时读取而不会发生任何阻塞。 这是通过基于并发级别将Map划分为不同部分并在更新期间仅锁定Map的一部分来实现的。 默认并发级别为16,因此Map分为16个部分,每个部分由不同的锁控制。 这意味着,16个线程可以同时在Map上运行,直到它们在Map的不同部分上运行。 这使ConcurrentHashMap具有高性能,尽管保持线程安全。

16是地图将被拆分的默认区域数。 在读取器线程的情况下,ConcurrentHashMap完成(几乎在所有情况下)都没有锁定。 编写器线程的数量是您需要担心的事情。 这个数字应该等于你拥有的地区数量。