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

Jed Wesley-Smith jed at atlassian.com
Mon Aug 13 20:29:29 EDT 2007


Basically you are describing the memoizer pattern in JCIP 5.6. There is 
an implementation in there that works pretty well. We did a similar 
implementation for JIRA that is described here: 
http://blogs.atlassian.com/developer/2007/02/preventing_concurrent_operatio.html 
although this one is specifically for preventing concurrent database 
inserts of the same value and does not cache them further.

Bob Lee's Guice framework has a memoized cache implementation that is 
rather nice as well, with just an abstract create method you implement 
to resolve the value. It has the benefit of being able to specify 
Strong/Soft/Weak keys and values (although he has moved the 
implementation to an internal package since Guice was first released). 
You can find that here: 
http://google-guice.googlecode.com/svn/trunk/src/com/google/inject/internal/ReferenceCache.java

I don't know if a juc library class makes complete sense as there are a 
few interesting and subtle edge-cases you want to handle yourself - as 
well as a few sharp edges - as the differences in the above 
implementations show.

Rowlands, Ben (IT) wrote:
> I often find a need for an API like:
>
>   public V createIfAbsent( K key, Callable<V> creator ) throws
> ExcecutionException
>
> Similar in operation to putIfAbsent() but taking a callback that is used
> to resolve the value if one isn't found at at the key. 
>
> A very common use-case of this is when we are using the Map to cache
> values (for example, from a database query). We only want to execute the
> database query if the value isn't already in the map so we can't use
> putIfAbsent() directly and we end up wrapping the Map using a
> lock-per-key or some other technique.
>
> I know this kind of behaviour can be achieved using a
> FutureTask/Executor etc (as described in "Concurrency in Practice")
> however it seems such a useful primitive that I think it would be useful
> to add to the ConcurrentMap API (or a new API in JUC) and would avoid
> the copy/paste or need to roll your own implementation each time (add
> will be even more succinct with closure support :). A slight difference
> in the behaviour of this API is that if the creator fails with an
> exception subsequent threads can have a go at creating the value rather
> than forcing them to fail with the original exception.
>
> The simple implementation below demonstrates this API using a
> lock-per-key (note, createIfAbsent() -> getOrCreate()). 
>
> Are there any plans for this sort of API in JUC? (or is there a 1-2 line
> equivalent that I've overlooked and could be used instead?)
>   
-- 
cheers,
- jed.



More information about the Concurrency-interest mailing list