Concurrent Map with fixed size

2019-06-16 10:20发布

问题:

I need a map with the following requirements :

  1. It should be highly concurrent. The put(), get() and remove() methods may be called by multiple threads simultaneously.

  2. It should be of fixed size. If the size of the HashMap reaches to the max value (e.g. 10000), addition of a new entry to the map should not be allowed. It CAN'T be LRU cache where the oldest entry gets removed on reaching maximum size.

ConcurrentHashMap may satisfy #1. But, not sure how #2 can be implemented on top of ConcurrentHashMap without impacting concurrency (Adding a custom put() method which will add to the map only when the size is lesser than the max size, needs to be "synchronized". That will defeat the purpose of using concurrent HashMap).

Please let me know your thoughts.

回答1:

You could implement a map that delegates to a ConcurrentHashMap, using a counting semaphore to limit the number of items in the map. The Semaphore class uses an atomically-updated int to keep track of the permits, so it wouldn't incur much extra overhead.



回答2:

You can do all these yourself, and the java SE arsenal alone might supply what you require, but I strongly recommend an easier and more scalable methodology as doing all this work yourself would be re-inventing the wheel. Try one of these in memory data grids :

  • Ehcache
  • Hazelcast

For instance in ehcache you can achieve what you want by a configuration similar to :

<cache 
 name="myCache"
 maxElementsInMemory="10000"
 eternal="true"
 overflowToDisk="false" />


回答3:

How about maintaining the size of Hashmap at all times to ensure the total number of elements inserted? You can use AtomicInteger so that you don't have to synchronize/lock a regular int and sacrifice the benefit of using ConcurrentHashMap.



回答4:

If using ConcurrentHashMap, which is the obvious choice here, then use the concurrencyLevel input to the constructor to increase the bandwidth - this segments the map into multiple zones to avoid conflicts of puts.