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