本文共 1298 字,大约阅读时间需要 4 分钟。
http://blog.csdn.net/michaelwubo/article/details/50865185
这篇文章名字叫《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假设现在缓存失效,并发线程5个,都创建了FutureTask,futureTask=new FutureTask (callable); futureValue=cacheMap.putIfAbsent(keyValue, futureTask); if(futureValue==null){ futureValue=futureTask; futureTask.run(); } return futureValue.get();}return res;
故最终5个中只有一个线程能够得到真正的 执行-阻塞-返回 过程,其它4个线程可能有两种情况:
(1)阻塞-返回
(2)直接返回
比用syn同步块清一色阻塞要好得多了