在前面已经学习过
Java并发编程-同步辅助类之CountDownLatch
Java并发编程-同步辅助类之CyclicBarrier
这篇文章介绍另一个辅助类Phaser,它是Jdk 1.7才添加的新的功能,它可以实现和CountDownLatch/CyclicBarrier类似的功能,但Phaser的功能更多,更加的灵活,它支持任务在多个点都进行同步,支持动态调整注册任务的数量。当然你也可以使用CountDownLatch,但你必须创建多个CountDownLatch对象,每一阶段都需要一个CountDownLatch对象。
操作方法
- Phaser(int parties),构造方法,与CountDownLatch一样,传入同步的线程数,也支持层次构造Phaser(Phaser parent)。
- register(),bulkRegister(int Parties),动态添加一个或多个参与者。
- arriveAndDeregister()方法,动态撤销线程在phaser的注册,通知phaser对象,该线程已经结束该阶段且不参与后面阶段。
- isTerminated(),当phaser没有参与同步的线程时(或者onAdvance返回true),phaser是终止态(如果phaser进入终止态arriveAndAwaitAdvance()和awaitAdvance()都会立即返回,不在等待)isTerminated返回true。
- arrive()方法,通知phaser该线程已经完成该阶段,但不等待其他线程。
- arriveAndAwaitAdvance()方法,类似await()方法,记录到达线程数,阻塞等待其他线程到达同步点后再继续执行。
- awaitAdvance(int phase) /awaitAdvanceInterruptibly(int phase) ,传入阶段数,只有当前阶段等于phase阶段时才阻塞等待。后者如果线程在休眠被中断会抛出InterruptedException异常(phaser的其他方法对中断都不会抛出异常)。
- onAdvance(int phase, int registeredParties)方法。参数phase是阶段数,每经过一个阶段该数加1,registeredParties是当前参与的线程数。此方法有2个作用:1、当每一个阶段执行完毕,此方法会被自动调用,因此,重载此方法写入的代码会在每个阶段执行完毕时执行,相当于CyclicBarrier的barrierAction。2、当此方法返回true时,意味着Phaser被终止,因此可以巧妙的设置此方法的返回值来终止所有线程。例如:若此方法返回值为 phase>=3,其含义为当整个线程执行了4个阶段后,程序终止。
- forceTermination()方法,强制phaser进入终止态。
使用实例
对在CountDownLatch中的例子使用Phaser代替CountDownLatch进行改进:
package MyThread;
import java.util.concurrent.Phaser;
public class Match {
// 模拟了100米赛跑,10名选手,只等裁判一声令下。当所有人都到达终点时,比赛结束。
public static void main(String[] args) throws InterruptedException {
final Phaser phaser=new Phaser() ;
// 十名选手
for (int index = ; index < ; index++) {
phaser.register();
new Thread(new player(phaser),"player"+index).start();
}
System.out.println("Game Start");
//注销当前线程,比赛开始
phaser.arriveAndDeregister();
//是否非终止态一直等待
while(!phaser.isTerminated()){
}
System.out.println("Game Over");
}
}
class player implements Runnable{
private final Phaser phaser ;
player(Phaser phaser){
this.phaser=phaser;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
// 第一阶段——等待创建好所有线程再开始
phaser.arriveAndAwaitAdvance();
// 第二阶段——等待所有选手准备好再开始
Thread.sleep((long) (Math.random() * ));
System.out.println(Thread.currentThread().getName() + " ready");
phaser.arriveAndAwaitAdvance();
// 第三阶段——等待所有选手准备好到达,到达后,该线程从phaser中注销,不在进行下面的阶段。
Thread.sleep((long) (Math.random() * ));
System.out.println(Thread.currentThread().getName() + " arrived");
phaser.arriveAndDeregister();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
其他文章:http://whitesock.iteye.com/blog/1135457
http://blog.csdn.net/escaflone/article/details/10418651
其他同步辅助类:
Java并发编程-同步辅助类之Exchanger
Java并发编程-同步辅助类之CyclicBarrier
Java并发编程-同步辅助类之CountDownLatch
Java并发编程-同步辅助类之Semaphore