[concurrency-interest] java.util.collections

Doug Lea dl@cs.oswego.edu
Wed, 11 Feb 2004 07:34:16 -0500


Kaspar wrote:

> we should probably, for consistancy, add some methods to 
> java.util.Collections
> 
> Collections.unmodifiableQueue(Queue<T> s)
> Collections.synchronizedQueue(Queue<T> s)
> Collections.checkedQueue(Queue<T> s)
> 
> and perhaps also
> Collections.emptyQueue()
> Collections.singletonQueue(T o)

You are right that adding such static methods in Collections might
have been a nice touch. (Well, except for synchronizedQueue. See
below.)  But I can't see it happening for Tiger. While I can't rule it
out, we are now at the point in release process where the only changes
that are supposed to make it in are bugfixes.  

(There is an inevitable clash here between JCP JSR process and JDK
release process. Even if we decided to officially add such things to
JSR166 spec, they wouldn't make release, so there is not much point in
doing so.)

Dmitry wrote on the similar...

> Just quickly evaluate the code of ConcurrentHashMap in JSK 1.5b1.
> May be I miss something, but I realise that it pretty easy
> (well, not SO easy but possible)
> write 
>         Map Collections.concurrentMap(Map map)
> as wrapper. 
> 
> Because it will obviously need ConcurrentTreeMap and it just ugly to
> write the lock/ unlock  and duplication the code of TreeMap too.
> 

We thought about things along these lines. It would be possible to
create a wrapper using ReentrantReadWriteLocks to produce classes that
have approximately the same properties as ConcurrentHashMap, but for
other map implementations. These wouldn't be as fast as custom classes
like ConcurrentHashMap, but are still sometimes useful.
(dl.util.concurrent contains a similar wrapper.)  And in the
particular case of TreeMap, this works pretty well -- a code sketch of
how to do this is in the ReentrantReadWriteLock javadoc as a usage
example, and one of our JSR166 test programs does it out more fully to
check functionality and performance.

But this technique works only if the underlying Map class conforms to
assumptions that pure read/retrieval methods have no
writes/side-effects. There's no way that a wrapper class can check
such assumptions, and we can't expect users of this class to always
know if the assumptions hold. And when they do not hold, you can get
serious corruption of underlying data structures.  So the only
conclusion we could reach is that we should not supply it, but
tell/show people how to do it themselves when they are sure it
applies.

-Doug