Is it appropriate to use AtomicReference.compareAndSet to set a reference to the results of a database call?

走远了吗. 提交于 2019-12-06 06:33:57

问题


I am implementing a simple cache with the cache stored as an AtomicReference.

private AtomicReference<Map<String, String>> cacheData;

The cache object should be populated (lazily) from a database table.

I provide a method to return the cache data to a caller, but if the data is null (ie. not loaded), then the code needs to load the data from the database. To avoid synchronized I thought of using the compareAndSet() method:

public Object getCacheData() {
  cacheData.compareAndSet(null, getDataFromDatabase()); // atomic reload only if data not set!
  return Collections.unmodifiableMap(cacheData.get());
}

Is it ok to use compareAndSet in this way ie. to involve a database call as part of the atomic action? Is it any better/worse than just synchronizing the method?

Many thanks for any advice..


回答1:


You do not achieve expected behaviour. This expression:

cacheData.compareAndSet(null, getDataFromDatabase())

will always call getDataFromDatabase() first. This means that it doesn't matter if the data was cached or not. If it was, you still call the database, but discard the results. The cache is working, but the performance is equally poor.

Consider this instead:

if(cacheData.get() == null) {
    cacheData.compareAndSet(null, unmodifiableMap(getDataFromDatabase()));
}
return cacheData.get());

It's not perfect (still getDataFromDatabase() can be called multiple times at the beginning), but will work later as expected. Also I moved Collections.unmodifiableMap() earlier so that you don't have to wrap the same map over and over again.

Which brings us to even simpler implementation (no synchronized or AtomicReference needed):

private volatile Map<String, String> cacheData;

if(cacheData == null) {
  cacheData = unmodifiableMap(getDataFromDatabase());
}
return cacheData;


来源:https://stackoverflow.com/questions/12992478/is-it-appropriate-to-use-atomicreference-compareandset-to-set-a-reference-to-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!