[concurrency-interest] Adding a createIfAbsent() API?

Bob Lee crazybob at crazybob.org
Tue Aug 14 10:02:41 EDT 2007


A general purpose createIfAbsent() should ensure only one value gets
created. As Jed pointed out, ReferenceCache strikes a pretty good balance:
http://google-guice.googlecode.com/svn/trunk/src/com/google/inject/internal/AbstractReferenceCache.java

You could implement this as a set of simple function classes (classes with
one method each) which delegate to a ConcurrentMap.

You probably want one where you can pass in the callback every time, and
another where you can pass in the callback once at construction time. Heck,
you might as well have one where you can pass in a new value every time.

You might also want versions which can get() interruptibly (i.e. it throws
InterruptedException).

If you delegate to any old ConcurrentMap, you'd probably have to tell the
function about your comparison strategy: equals or identity.

Exception transparency (passing exceptions from the callback through without
wrapping them) makes client code considerably simpler. As Neal pointed out,
this API could benefit in multiple ways from closures.

I thought the JCache JSR might be the place to design this API, and I'm in
the process of joining it for that very purpose, but I have no idea what
they've been working on and whether it's actually a good fit.

In any case, I really want to get something like this into the JDK also.

Bob

On 8/14/07, Joe Bowbeer <joe.bowbeer at gmail.com> wrote:
>
> It just occurred to me that createIfAbsent, if it were to exist,
> should probably return the current mapping rather than the previous
> one.  That way it will return the newly constructed value when it is
> used.  This is the opposite of putIfAbsent.
>
> 1a. If the createIfAbsent implementation doesn't use locking, I assume
> it must be allowed to throw away the constructed value:
>
>   if (!containsKey(key))
>     putIfAbsent(key, callable.call());
>   return get(key);
>
> 1b. However, if the value is expensive to create, then some kind of
> cleanup is more likely to be needed when it is discarded:
>
>   V val = get(key);
>   if (val == null) {
>     V next = callable.call();
>     val = putIfAbsent(key, next);
>     if (val == null)
>       val = next;
>     else
>       next.dispose();
>   }
>   return val;
>
> --Joe
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at altair.cs.oswego.edu
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/attachments/20070814/c9c315b6/attachment.html 


More information about the Concurrency-interest mailing list