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

2022-09-02 03:24:15

我正在并发哈希映射中处理大约1000个元素。默认并发级别为 16 。任何人都可以帮助我使用一些算法或因素,从中我可以确定适合我的场景的并发级别,或者并发级别如何影响多个线程的处理。

   ConcurrentHashMap<String, String> map=new ConcurrentHashMap<String, String>(500,1,20);             

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


答案 1

根据文档:

更新操作之间允许的并发性由可选的构造函数参数(默认)指导,该参数用作内部大小的提示。该表在内部分区,以尝试允许指定数量的并发更新而不会发生争用。因为哈希表中的位置基本上是随机的,所以实际的并发性会有所不同。理想情况下,您应该选择一个值来容纳任意数量的线程并发修改表。使用明显高于所需值的值会浪费空间和时间,而明显较低的值可能会导致线程争用。concurrencyLevel16

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

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


答案 2

Java 8:

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

来自源代码的代码:

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

并且构造函数的参数只是像文档所说的那样将其用作大小提示。

并发级别 - 估计的并发更新线程数。实现可以将此值用作大小调整提示。

来源:

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


推荐