Source:
<code>public BoundedConcurrentHashMap(int capacity, int concurrencyLevel, Eviction evictionStrategy, EvictionListener<K, V> evictionListener, Equivalence<K> keyEquivalence, Equivalence<V> valueEquivalence) { this.keyEquivalence = keyEquivalence; this.valueEquivalence = valueEquivalence; if (capacity < 0 || concurrencyLevel <= 0) { throw new IllegalArgumentException(); } concurrencyLevel = Math.min(capacity / 2, concurrencyLevel); concurrencyLevel = Math.max(concurrencyLevel, 1); if (capacity < concurrencyLevel * 2 && capacity != 1) { throw new IllegalArgumentException("Maximum capacity has to be at least twice the concurrencyLevel"); } if (evictionStrategy == null || evictionListener == null) { throw new IllegalArgumentException(); } Properties p = new Properties(); p.put("maxThreads", Runtime.getRuntime().availableProcessors()); p.put("coreThreads", 0); p.put("queueSize", 100); p.put("threadNamePrefix", "BCHM"); ExecutorFactory ef = new DefaultExecutorFactory(); <START> executor = ef.getExecutor(p); <END> this.evictionListener = evictionListener; if (concurrencyLevel > MAX_SEGMENTS) { concurrencyLevel = MAX_SEGMENTS; } int sshift = 0; int ssize = 1; while (ssize < concurrencyLevel) { ++sshift; ssize <<= 1; } segmentShift = 32 - sshift; segmentMask = ssize - 1; this.segments = Segment.newArray(ssize); if (capacity > MAXIMUM_CAPACITY) { capacity = MAXIMUM_CAPACITY; } int c = capacity / ssize; int cap = 1; while (cap < c) { cap <<= 1; } this.evictCap = c; for (int i = 0; i < this.segments.length; ++i) { this.segments[i] = new Segment<K, V>(cap, DEFAULT_LOAD_FACTOR, evictionStrategy, this); } }</code><technical_language>I in action, I if ForkJoinPool.commonPool() instead :) ThreadPoolExecutor is finicky, if set a queue size fill it, end a single thread. if do fill queue, rejection policy DefaultExecutorFactory is CallerRunsPolicy, means generate new tasks for a while. in all, I a ForkJoinPool better, size-based eviction</technical_language>

Target:
public BoundedConcurrentHashMap(int capacity, int concurrencyLevel, Eviction evictionStrategy, EvictionListener<K, V> evictionListener, Equivalence<K> keyEquivalence, Equivalence<V> valueEquivalence) { this.keyEquivalence = keyEquivalence; this.valueEquivalence = valueEquivalence; if (capacity < 0 || concurrencyLevel <= 0) { throw new IllegalArgumentException(); } concurrencyLevel = Math.min(capacity / 2, concurrencyLevel); concurrencyLevel = Math.max(concurrencyLevel, 1); if (capacity < concurrencyLevel * 2 && capacity != 1) { throw new IllegalArgumentException("Maximum capacity has to be at least twice the concurrencyLevel"); } if (evictionStrategy == null || evictionListener == null) { throw new IllegalArgumentException(); } executor = ForkJoinPool.commonPool(); this.evictionListener = evictionListener; if (concurrencyLevel > MAX_SEGMENTS) { concurrencyLevel = MAX_SEGMENTS; } int sshift = 0; int ssize = 1; while (ssize < concurrencyLevel) { ++sshift; ssize <<= 1; } segmentShift = 32 - sshift; segmentMask = ssize - 1; this.segments = Segment.newArray(ssize); if (capacity > MAXIMUM_CAPACITY) { capacity = MAXIMUM_CAPACITY; } int c = capacity / ssize; int cap = 1; while (cap < c) { cap <<= 1; } this.evictCap = c; for (int i = 0; i < this.segments.length; ++i) { this.segments[i] = new Segment<K, V>(cap, DEFAULT_LOAD_FACTOR, evictionStrategy, this); } }