[concurrency-interest] memoizer cache
Christian Vest Hansen
karmazilla at gmail.com
Fri Oct 21 12:18:43 EDT 2011
Oh, it seems I overlooked the requirement to not block other threads when a
value is being re-created.
On Fri, Oct 21, 2011 at 18:11, Christian Vest Hansen
<karmazilla at gmail.com>wrote:
>
> One thing that comes to mind is this:
> If you determine that the value you are about to return has expired, then
> you could replace(key, entry, null) and recursively call get(key) again. If
> the replace() call returns `false` then someone got ahead of you and already
> put a null or a new CountDownLatch in there, and the get() call will deal
> with it. Otherwise it will look, to the following get() call, as if the
> entry never existed and get() will create it for you. So you don't really
> need to check the return value of replace() with this approach.
> If you do it this way then I guess you don't need the Entry class either.
> As far as my quick glancing can tell.
>
>
> On Fri, Oct 21, 2011 at 16:39, bhm <bheem at sbcglobal.net> wrote:
>
>> I'm trying to build a cache for configuration objects for my projects-
>> Requirements:
>> 1 only one instance per key should be created, either because its absent
>> for a given key or its expired (in that case it will be recreated).
>> 2 most common path asking for a value for a key should not block or
>> synchronize.
>> 3 when a value doesnt exists for a key, one thread should create the
>> instance
>> of value and put in the cache, other threads asking for same key should
>> wait
>> till thats complete.
>> 4 if a value is expired, one thread should (re)create the instance of
>> value
>> and other threads asking for same key (when one thread is recreating it)
>> should use expired instance of value and should not block.
>>
>> My code is largely derived from Christian's reply
>>
>> http://cs.oswego.edu/pipermail/concurrency-interest/2010-November/007469.html
>>
>> Please comment or suggest on following, Thanks for you help.
>>
>> final ConcurrentMap<K, Object> store = new ConcurrentHashMap<K,
>> Object>();
>>
>> V get(K key) {
>> Object ret = store.get(key);
>>
>> if (ret == null) {
>> CountDownLatch latch = new CountDownLatch(1);
>> ret = store.putIfAbsent(key, latch);
>> if (null == ret) {
>> ret = new Entry<V>(factory.create(key));
>> store.replace(key, ret);
>> latch.countDown();
>> }
>> }
>>
>> if (ret instanceof CountDownLatch) {
>> try {((CountDownLatch) ret).await();} // till new value is
>> created
>> catch (InterruptedException e) {throw new RuntimeException(e);}
>> ret = store.get(key); // get new value
>> } else {
>> Entry<V> entry = (Entry<V>) ret;
>>
>> if (evictionpolicy != null &&
>> evictionpolicy.isExpired(entry.v)) {
>> final AtomicInteger sync = entry.sync;
>>
>> if (sync.compareAndSet(0, 1)) { // otherwise retrun old
>> value
>> try {
>> entry = (Entry<V>) store.get(key); // get again
>> if (evictionpolicy.isExpired(entry.v)) { //
>> double-check
>> Entry<V> newval = new
>> Entry<V>(factory.create(key));
>> store.replace(key, newval);
>> ret = newval;
>> }
>> }
>> catch (Throwable catchall) {
>> catchall.printStackTrace(System.err);//return old
>> value
>> }
>> finally {sync.set(0);/*unlock*/}
>> }
>> }
>> }
>>
>> return ((Entry<V>) ret).v;
>> }
>>
>> class Entry<V> {
>> final AtomicInteger sync = new AtomicInteger(0);
>> final V v;
>> Entry(V v) {this.v=v;}
>> }
>>
>>
>> form other discussions about similar topics in the list, I understand
>> there are
>> libraries to do that (MapMaker etc.), I wanted something specific, small,
>> just
>> to slove the given problem and avoid generalization.
>> I couldnt get jcp's Memoizer to work when cache entries could expire. Its
>> good
>> for lazy one time load.
>>
>> Thanks again.
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>
>
>
> --
> Venlig hilsen / Kind regards,
> Christian Vest Hansen.
>
--
Venlig hilsen / Kind regards,
Christian Vest Hansen.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20111021/c7e3be88/attachment.html>
More information about the Concurrency-interest
mailing list