RFR 8005704: Update ConcurrentHashMap to v8

Doug Lea dl at cs.oswego.edu
Fri May 31 10:31:51 UTC 2013

On 05/30/13 14:18, Mike Duigou wrote:
>>> - I don't see the advantage to exposing the ConcurrentHashMap.KeySetView type
>>> particularly for newKeySet(). Why not return Set<K>? The additional methods
>>> don't seem to offer much that's desirable for the newKeySet() case.
>> Since we don't have a ConcurrentSet interface, people are reduced to
>> instanceof checks to see if they have a concurrent one. But without
>> exposing the class, they couldn't even do this, so complained. This
>> will arise more frequently with  j.u.streams.Collectors.
> I'd rather introduce a vacuous ConcurrentSet than expose ConcurrentHashMap.KeySetView. Any reason not to add it?

Thinking this over a bit and asking a few others, it seems that
adding ConcurrentSet at this point would cause more problems
than it solves. As one example, you'd want all ConcurrentMap.keySet()
methods to return one, but we can't retrospectively spec this.

Note that CHM.newKeySet gives exactly the same view class for
CHM that j.u.HashSet does for j.u.HashMap, but also allows
transient projection (method CHM.keySet(value)) that you
cannot do with Hash{Map,Set}.
We also don't want to waste the name ConcurrentHashSet for
this, to leave open the possibility of someday creating a
custom unattached class optimized solely for use as Set.

>>> - I think there could be more complete description of the
>>> parallelismThreshold and interaction with common pool.

> only one change

> Using a value of {@code 1} results in maximal parallelism by partitioning into
> enough subtasks to fully utilize the {@link ForkJoinPool#commonPool()}.

Sure; thanks. I reworked a little to avoid redundant need for last sentence:

  * <p>These bulk operations accept a {@code parallelismThreshold}
  * argument. Methods proceed sequentially if the current map size is
  * estimated to be less than the given threshold. Using a value of
  * {@code Long.MAX_VALUE} suppresses all parallelism.  Using a value
  * of {@code 1} results in maximal parallelism by partitioning into
  * enough subtasks to fully utilize the {@link
  * ForkJoinPool#commonPool()} that is used for all parallel
  * computations. Normally, you would initially choose one of these
  * extreme values, and then measure performance of using in-between
  * values that trade off overhead versus throughput.

More information about the core-libs-dev mailing list