学习:一个并发的Cache
浏览:4845次 出处信息
以下是代码片段: public class Memoizer implements Computable { private final ConcurrentMap> cache = new ConcurrentHashMap>(); private final Computable c; public Memoizer(Computable c) { this.c = c; } public V compute(final A arg) throws InterruptedException { while (true) { Future f = cache.get(arg); if (f == null) { Callable eval = new Callable() { public V call() throws InterruptedException { return c.compute(arg); } }; FutureTask ft = new FutureTask(eval); f = cache.putIfAbsent(arg, ft); //先把FutureTask放进去再说 if (f == null) { f = ft; ft.run(); } //开始计算 } try { return f.get(); } catch (CancellationException e) { cache.remove(arg, f); } catch (ExecutionException e) { throw launderThrowable(e.getCause()); } } } } |
这个Cache的设计很有意思, 考虑了很多并发的因素. Cache用简单的Map方式来实现.
1) 使用ConcurrentHashMap来存放计算结果
2) 最有趣的一点, ConcurrentHashMap 里存放的内容是 FutureTask. (为什么? 这相当于放一个Latch)
3) 使用了FutureTask来调度计算, 这样多个线程可以分别进行针对不同的参数的计算
4) 基于FutureTask的特性, 先把FutureTask放进了cache, 再对FutureTask计算
5) 用了一个 while(true) 无限循环…
(为什么? 因为如果发现已经有一个线程中进行相同的计算的话, 就直接等待计算结果. 但是等待过程中, 如果FutureTask被中断了呢? 抓住异常, 再等…)
6) 使用putIfAbsent操作, 避免出现两个线程都进行相同的计算
建议继续学习:
- 一种常见的并发编程场景的处理 (阅读:22446)
- Rolling cURL: PHP并发最佳实践 (阅读:10097)
- 查看 Apache并发请求数及其TCP连接状态 (阅读:8073)
- 大型高并发高负载网站的系统架构分析 (阅读:7554)
- 大并发下的高性能编程 – 改进的(用户态)自旋锁 (阅读:6896)
- Buffer和cache的区别是什么? (阅读:6716)
- 并发编程系列之一:锁的意义 (阅读:5624)
- 谈冷热数据 (阅读:5570)
- Linux操作系统中内存buffer和cache的区别 (阅读:5225)
- 并发框架Disruptor译文 (阅读:4869)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:用 sscanf 解析字符串时结尾的判断
后一篇:排头兵PHP中文分词,纯PHP版实现 >>
文章信息
- 作者:tangfl 来源: 福林雨-博客
- 标签: Cache 并发
- 发布时间:2010-08-02 22:59:47
建议继续学习
近3天十大热文
- [604] 招聘技巧一二
- [17] 我的git笔记
- [16] 在ssh服务里使用chroot
- [16] 密度聚类算法之OPTICS
- [14] 数据分析中常用的数据模型
- [14] Android用户界面设计:表格布局
- [14] 豆瓣是啥?
- [13] 配合jquery实现异步加载页面元素
- [13] jQuery性能优化指南
- [12] linux内核研究笔记(一)内存管理 – p