本文主要是介绍结合 ConcurrentHashMap.putIfAbsent 与 Futrue 实现本地缓存防击穿,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
http://blog.csdn.net/michaelwubo/article/details/50865185
Java 高并发缓存与Guava Cache
这篇文章名字叫《Java 高并发缓存与Guava Cache》,但最核心的是如何高效的防止本地缓存击穿
业务模型:
res = cache.get(key);
if(res == null) {value = sql;cach.put(key, value);return value;
}
return res;
这个代码多线程里不行:
在多线程时,出现了在缓存里没有缓存时,会执行一样执行多次的业务数据并返回处理的数据,我们分析一下出现这种情况的:
(1)当线程T1访问cacheMap里面有没有,这时根据业务到后台处理业务数据并返回处理数据,并放入缓存。
(2)当线程T2访问cacheMap里面同样也没有,也把根据业务到后台处理业务数据并返回处理数据,并放入缓存。
res = cache.get(key);
if(res == null) {synchronized(this) {oldValue = cache.get(key);if(oldValue == null) {value = sql;cach.put(key, value);return value;} else return oldValue;}}
return res;
然后就会想到这个代码对性能损伤较大,而且不适用于集群环境。
res = cache.get(key);
if(res == null) {FutureTask<V> futureTask=new FutureTask<V>(callable); futureValue=cacheMap.putIfAbsent(keyValue, futureTask); if(futureValue==null){ futureValue=futureTask; futureTask.run(); } return futureValue.get();
}
return res;
假设现在缓存失效,并发线程5个,都创建了FutureTask,
故最终5个中只有一个线程能够得到真正的 执行-阻塞-返回 过程,其它4个线程可能有两种情况:
(1)阻塞-返回
(2)直接返回
比用syn同步块清一色阻塞要好得多了
这篇关于结合 ConcurrentHashMap.putIfAbsent 与 Futrue 实现本地缓存防击穿的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!