Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use and set appropriately concurrency level for ConcurrentHashMap?

Tags:

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 the concurrency level suitable for my scenario or in what way a concurrency level affects the processing of multiple threads .

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

20 is my concurrency level (dummy value) .Need to set this efficiently

like image 801
csk Avatar asked Aug 28 '13 12:08

csk


People also ask

Can we change the concurrency level in ConcurrentHashMap?

The default concurrency-level of ConcurrentHashMap is 16. In ConcurrentHashMap, at a time any number of threads can perform retrieval operation but for updated in the object, the thread must lock the particular segment in which the thread wants to operate.

What is concurrency level?

The concurrency level attribute was introduced with Virtual I/O Server (VIOS) version 2.2. 2.0 and is used to control the amount, and configuration, of resources that are allocated to a partition mobility operation by the mover service partition (MSP).

What is default size of ConcurrentHashMap?

Creates a new, empty map with a default initial capacity (16), load factor (0.75) and concurrencyLevel (16).

How many threads can work on ConcurrentHashMap?

A ConcurrentHashMap has internal final class called Segment so we can say that ConcurrentHashMap is internally divided in segments of size 32, so at max 32 threads can work at a time.


2 Answers

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?

like image 81
Tala Avatar answered Sep 25 '22 23:09

Tala


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.

like image 44
Tony Avatar answered Sep 21 '22 23:09

Tony