Beyond Threading
Java线程模型的优点在于能够清晰的model应用逻辑流,通过对应OS里物理线程,可以利用多个处理器,或者通过切换让CPU利用率不同的线程共享一个处理器。
但是这种把应用的逻辑线程直接搬到OS的物理线程上运行的方式(*)也存在弊端:
- Heavy weight,每个OS线程都需要内存和自己的堆栈等资源
- Context switching,及其引起的低效率(cache污染,线程饥饿,优先级逆转..)
- Synchronization & lock, 需用同步访问share memory和资源,而如何保证安全性,同时取得最大的效率, 如何平衡safety和liveness的关系解决起来绝非易事.
引起这些低效率很大原因是现有线程模式是粗线条的黑箱模式,runtime系统并不知道线程在干什么和它们之间的依赖关系,只是通过强制的方式(time slicing, locks, monitors)来调度协作。
另一种更加透明的方式,即把现有的线程分解成更小,轻量级的单位Task, 显示的描述这些任务单位之间的并行性和相互依赖关系,包括对同一资源的访问,有了这些信息,系统可以更高效的方式来执行这些任务。
具体的实现包括:
- Apple Grand Central Dispatch
- Microsoft Task Parallel Library
- Intel Thread Building Block
- Google Go Language
这些技术的模型都基于CSP(communicating sequential processing)
CSP模型里每个Process 内部是串行的,而Process和Process之间是并行的。这样overhead最小,更不需要有同步/锁的概念.系统的scheduler把高层模型映射到Runtime运行系统。
Runtime运行系统维护和cpu核数对等的线程池.每一个线程有自己的任务队列- double ended queue。线程从队列的头取得任务并执行,当本地队列为空时,则会从其他队列”偷”任务过来。通常情况下因为只有一个线程会访问队列的头所以不会有竞争,而队列尾出现竞争的情况也是空闲线程完成,实现了动态的自动的负载均衡和最高的CPU运行效率.
如果说GCD等基于task模型还比较低层的话,以Erlang为代表的Actor模型提供了更接近OO的抽象,同样是基于CSP,只不过Actor模型传的是message而不是closure。
Java库/框架推荐:
- 开源的HawtDispatch库,Apple GCD 的Java实现, 作者也是ActiveMQ的开发人员,这个库短小精悍,可谓是最容易帮助上手Task based programming的工具了. http://hawtdispatch.fusesource.org/
- 开源的Akka平台,构建于HawtDispatch之上, 功能强大:actor model, STM, 分布式+容错功能(接近Erlang). http://akkasource.org/
(*) Java5引入的Executor框架/ThreadPool只是改进但是没有解决根本的问题,另外Thread pool的queue本身是可能的瓶颈
建议继续学习:
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:fankong 来源: 淘宝数据平台与产品部官方博客 tbdata.org
- 标签: CSP 线程模型
- 发布时间:2010-12-30 22:44:42
- [70] Twitter/微博客的学习摘要
- [64] find命令的一点注意事项
- [63] 如何拿下简短的域名
- [63] IOS安全–浅谈关于IOS加固的几种方法
- [62] android 开发入门
- [61] Go Reflect 性能
- [60] 流程管理与用户研究
- [59] Oracle MTS模式下 进程地址与会话信
- [59] 图书馆的世界纪录
- [57] 读书笔记-壹百度:百度十年千倍的29条法则