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
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.
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).
Creates a new, empty map with a default initial capacity (16), load factor (0.75) and concurrencyLevel (16).
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.
According to docs:
The allowed concurrency among update operations is guided by the optional
concurrencyLevel
constructor argument (default16
), 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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With