java并发编程实战-构建高效且可伸缩的结果缓存
2017-07-08 14:41
330 查看
构建高效且可伸缩的结果缓存
1,缓存在服务器应用程序中是一个非常重要的组件。
2,以下讲解一个高效且可伸缩的缓存示例
代码如下
1,缓存在服务器应用程序中是一个非常重要的组件。
2,以下讲解一个高效且可伸缩的缓存示例
代码如下
public class CacheSample<IN, OUT> { /* * 缓存类容器 * 1,选择线程安全的ConcurrentMap,它提供了并发读写的线程安全,以及“先检查再执行”这样的原子操作putIfAbsent * 2,选择Future,避免直接存储计算结果值,导致高并发下多个线程同时计算同一个值的情况 */ private final ConcurrentMap<IN, Future<OUT>> cache = new ConcurrentHashMap<IN, Future<OUT>>(); public OUT doSomething(final IN arg) throws InterruptedException { while (true) { Future<OUT> f = cache.get(arg); if (f == null) { // 如果没有IN对应的Future,则创建Future Callable<OUT> eval = new Callable<OUT>() { public OUT call() throws InterruptedException { return doing(arg); } }; FutureTask<OUT> ft = new FutureTask<OUT>(eval); // 通过putIfAbsent完成“先检查再添加”的原子操作 // putIfAbsent如果已存在则返回已存在的值,如果不存在则添加新建的Future并返回null f = cache.putIfAbsent(arg, ft); if (f == null) { // 如果新添加进缓存,则启动计算 f = ft; ft.run(); } } try { // 不管f是新创建的还是通过缓存中获取的,如果Future还没计算结束就阻塞,如果计算结束就获取值 return f.get(); } catch (CancellationException e) { // 当某个计算被取消或者失败,需要从缓存中移除该IN及对应的Future // 否则,将持续性获取不到正确的值,但同时又无法再进行新的计算(缓存污染) cache.remove(arg, f); } catch (ExecutionException e) { throw LaunderThrowable.launderThrowable(e.getCause()); } } } private OUT doing(final IN arg){ // 非常耗时的处理过程................ return null; } }
相关文章推荐
- 《Java并发编程实战》 阅读笔记 构建高效且可伸缩的结果缓存
- Java并发(具体实例)—— 构建高效且可伸缩的结果缓存
- java并发编程实践学习(5)构建块为计算结果建立高效,可伸缩的高速缓存
- java并发工具类构建高效且可伸缩的结果缓存
- java多线程(十) 之 构建高效且可伸缩的结果缓存
- 构建高效且可伸缩的结果缓存
- 构建高效且可伸缩的结果缓存
- 构建高效且可伸缩的结果缓存引申的并发测试规范化
- 【JAVA并发编程实战】5、构建高效且可伸缩的结果缓存
- java并发——构建高效且可伸缩的结果缓存
- Java并发(具体实例)——构建高效且可伸缩的结果缓存
- 一头扎进多线程-构建高效且可伸缩的结果缓存
- 构建高效可伸缩的结果缓存
- 高效可伸缩的结果缓存
- 构建高效的结果缓存
- 【多线程_提高篇】 创建高效且可伸缩的结果缓存
- 高效且可伸缩的结果缓存
- Java趣谈——如何构建一个高效且可伸缩的缓存
- 高效可伸缩的结果缓存
- 构建高效可申缩的结果缓存