Friday 15 June 2012

java - Putting a value in a google guava loadingCache -



java - Putting a value in a google guava loadingCache -

this loading cache definition:

private class productvalue { private long regionavalue; private long regionbvalue; // constructor , general stuff here } private final loadingcache<productid, productvalue> productcache = cachebuilder.newbuilder() .expireafteraccess(4, timeunit.minutes) .build(new cacheloader<productid, productvalue>() { @override public productvalue load(final productid productid) throws exception { homecoming updateproductvalues(productid); } }); private productvalue updateproductvalues(final productid productid) { // read disk , homecoming }

now, i've utilize case i'm required set value of regiona or regionb in cache until next update happens. i'm utterly confused concurrency implications of logic i've:

public void setproductvalue(final productid productid, final boolean istypea, final long newvalue) throws executionexception { productvalue existingvalues = productcache.get(productid); // 1 if (istypea) { existingvalues.regionavalue = newvalue; } else { existingvalues.regionbvalue = newvalue; } productcache.put(productid, existingvalues); // 2 }

in 1 read reference of info stored in cache given key, thread safe because loading cache acts concurrent map. between 1 , 2 reference can overwritten other thread. since i've overwritten 'value' using reference existed in cache, need set key-value pair in cache? need line 2?

(disclaimer: not guava cache expert)

i think have 2 concurrency issues in code:

you have 2 operations mutate object in existingvalues, existingvalues.regionavalue = ... , existingvalues.setregionvalue(...). other threads can see state when 1 operation applied. think not wanted. (correct?) between get() , put() value may loaded 1 time again in cache , put() overwrites new value.

regarding 1:

if have more reads object writes, alternative utilize immutable object. don't touch instance re-create of original object, mutate, , set new object cache. way final state becomes visible.

regarding 2:

atomic cas operations can help here (e.g. jsr107 compatible caches). useful method boolean replace(k key, v oldvalue, v newvalue);

in google guava cas methods accessible via concurrentmap interface, can retrieve via asmap().

java multithreading caching concurrency guava

No comments:

Post a Comment