How to use and set appropriately concurrency level for ConcurrentHashMap?

后端 未结 5 1734
遥遥无期
遥遥无期 2020-12-17 09:20

I am working with around 1000 elements in concurrenthashmap . Default concurrency level is 16 . can anyone help me with some algorithm or factors from which i can identify t

相关标签:
5条回答
  • 2020-12-17 09:54

    Java 8:

    Now the ConcurrentHashMap does not use a fixed lock striping scheme at all, instead each bucket serves as a “stripe” using intrinsic synchronization.

    Code from source:

    /** 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) {
               ...
           }
    }
    

    And the constructor has the parameter just use it as a size hint as docs say.

    concurrencyLevel - the estimated number of concurrently updating threads. The implementation may use this value as a sizing hint.

    And the source:

    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;
    }
    

    So you don't need to consider it by yourself, ConcurrentHashMap will handle it for you.

    0 讨论(0)
  • 2020-12-17 10:06

    ConcurrentHashMap allows multiple readers to read concurrently without any blocking. This is achieved by partitioning Map into different parts based on concurrency level and locking only a portion of Map during updates. Default concurrency level is 16, and accordingly Map is divided into 16 part and each part is governed with different lock. This means, 16 thread can operate on Map simultaneously, until they are operating on different part of Map. This makes ConcurrentHashMap high performance despite keeping thread-safety intact.

    0 讨论(0)
  • 2020-12-17 10:08

    According to docs:

    The allowed concurrency among update operations is guided by the optional concurrencyLevel constructor argument (default 16), which is used as a hint for internal sizing. The table is internally partitioned to try to permit the indicated number of concurrent updates without contention. Because placement in hash tables is essentially random, the actual concurrency will vary. Ideally, you should choose a value to accommodate as many threads as will ever concurrently modify the table. Using a significantly higher value than you need can waste space and time, and a significantly lower value can lead to thread contention.

    So you need to answer 1 question:

    What is the number of threads that will ever concurrently modify the table?

    0 讨论(0)
  • 2020-12-17 10:12

    16 is the default number of regions that your map will be split into. ConcurrentHashMap, in case of reader threads, is done (in almost all cases) without locking at all. The number of writer threads is the thing you need to worry. And this number should be equal to the number of regions you have.

    0 讨论(0)
  • 2020-12-17 10:17

    So,concurrency level is the equal to to the writer threads.And map will also segmented equals to the value of concurrency level.

    0 讨论(0)
提交回复
热议问题