技术开发 频道

关注Java7的多核

  【IT168 技术文章】尽管Java SE 7的内容仍在不断变动,早期包含在其中的并发特性候选已经成形为jsr166y:一个fork/join框架和一个传递队列。InfoQ与Doug Lea谈及了这些特性及Java SE 7中的并发性。

  fork/join框架是一个“多核友好的、轻量级并行框架 ”,它支持并行编程风格,将问题递归拆分成多个更小片断,以并行和调配的方式解决,如同Java Fork/join框架 中描述的伪代码那样:

1 Result solve(Problem problem) {
2
3 if (problem is small) directly solve problem
4
5 else {
6
7 split problem into independent parts
8
9 fork new subtasks to solve each part
10
11 join all subtasks
12
13 compose result from subresults
14
15 }
16
17 }
18

  这确保了工作可以并行完成且在多核系统上运行良好:

  在Java 7 生命周期内,大的(32+)多核系统将大量出现,有了这个框架可以让人们对计算密集型任务获得相对简单的增速方法。目前,forkjoin在如Sun Niagaras和Azuls这样的机器上工作得最好,它们只是即将普及的并行处理器。Forkjoin在标准SMP上工作的也不错。总体来讲,少于4处理器的话你不并能获得太多增速效果——其主要目标是针对成打到成百处理器范围。

  假如充分分解任务的大小,那么创建一个线程的开销有可能超出执行该任务的开销。因此,fork/join框架使用与可用核数相匹配的适当大小的线程池,以减少这种频繁交换的开销。为避免线程空闲,框架包含了一个工作窃取方法,该方法可以使空闲线程从一个执行较慢的线程中窃取等待其处理的工作。该Java Fork/join框架 说明书描述了fork/join框架所使用的机制并展示了多核系统性能样例,还与其他相似并行编程框架进行了对比。

  Doug Lea描述了fork/join框架最可能的使用场景和采用过程:

  总之,我期望其使用曲线与其他并发工具雷同。最初,只有较少真正需要的人使用它们,但最终很难找到不依赖于它们的程序,它们常常深埋在底层基础架构组件中。因此,表面语法支持可能并不是那么重要——类库/组件开发者越是想合并它们,其用法越是表现的笨拙。

  理想的情况下,有几个使用层次:

  1. “并行做事”层次,语言或工具翻译成并行代码,同时检查安全性/活跃性。这仍部分处于研究领域。

  2. 安排集合的并行操作。——map、reduce、apply等等。那些想使用一次性操作特性操纵集合的程序员们,可以使用这些特性来提高常用处理类型的速度。(这是ListTasks、ArrayTasks等等层次)

  3. 手工生效forkjoin以解决特定问题。这是我正在全力投入的层次,以确保我们可能使用工作窃取框架来支持范围广泛的并行算法。(当前一些怪模怪样的和缺乏解释的方法,如isQuiescent是为这种高级用法设计的。多数程序只使用“fork”和“join”,但当你需要其他这些方法时,它们也被提供了。)

  4. 扩展框架以创建新类型的ForkJoinTasks等等。例如,那些需要事务的操作。只有很少量的人(例如,或许是Fortress运行时类库开发者)需要这么做,但是需要有足够的基础扩展钩子来才能做好。

  Java SE 7 的另外一个候选是TransferQueue。TransferQueue扩展了BlockingQueue接口,增加了生产方阻塞,生产者在两方都准备好时将一个对象传递给消费者。非阻塞和超时风格传递也是可用的。它适合于一些消息传送应用,这里传递是必须的,并且“去创建一个简单易用的线程池,其中有时任务必须同步传递”。

  传递队列和fork/join框架也许不是仅有的加入Java SE 7的并发特性。按照Doug Lea的说法,有正在进行中的新要求和需要加强的特性,包括可扩展计数器,一个ConcurrentIdentityHashMap,“增加原子包以更好支持专家模式微调内存模型效果”以及对java.util.Collections的算法改进。

0
相关文章