6.4 小结

本章介绍了Java并发API提供的最强大的同步机制之一:分段器。它的主要目的是为执行分为多阶段的算法的任务提供同步。在所有任务都完成上一阶段之前,任何任务都不能开始执行下一阶段。

分段器必须知道任务要进行同步的任务数量。必须使用构造函数、bulkRegister()方法或register()方法在分段器中注册任务。

分段器可以以不同方式同步任务。最常见的方式是使用arriveAndAwaitAdvance()方法告诉分段器,任务已经完成了一个阶段的执行,要继续执行下一阶段。该方法将休眠该线程直到剩下的任务都完成当前阶段为止。不过,也可以使用其他方法同步任务。arrive()方法用于通知分段器当前阶段已经完成,但是不会等待剩下的任务(使用该方法时要非常小心)。arriveAndDeregister()方法用于告知分段器当前阶段已经完成,而且并不想在分段器中继续等待(通常是因为已经完成了任务)。最后,awaitAdvance()方法可用于等待当前阶段结束。

通过使用onAdvance()方法,可以控制阶段变化,并且在所有任务都完成当前阶段且准备开始新阶段时执行代码。该方法在两个阶段执行的间隙被调用,并且接收阶段的编号和参与者在分段器中的编号作为参数。你可以扩展Phaser类,并且重载该方法以在两个阶段之间执行代码。

分段器可以处于活动和终止两种状态。同步任务时进入活动状态;完成自己的工作时进入终止状态。所有参与方调用arriveAndDeregister()方法时或者onAdvance()方法返回true值(默认情况下,总是返回false)时,分段器将进入终止状态。当Phaser类处于终止状态时,它不再接收新的参与方,而且同步方法将立即返回。

使用Phaser类实现了两个算法:关键字抽取算法和遗传算法。在这两个例子中,与算法的串行版本相比,并发版本在吞吐量上有了重要的增长。

下一章将介绍如何使用另一个Java并发框架解决特殊类型的问题。这就是Fork/Join框架,用于以并发方式执行那些可以采用分治算法进行求解的问题。它基于一个采用了特殊工作窃取算法的执行器,这种算法能够使执行器的性能最大化。