Phaser:阶段器。
官方文档中这样描述:
可重用的同步屏障,功能类似于CyclicBarrier和CountDownLatch,但是更为灵活。
与其他屏障不同,在Phaser上进行同步的已注册的party的数量会随时间变化。任务可以随时注册(使用register()或bulkRegister()),以及可以在任何到达的时候注销(使用arriveAndDeregister())。
该类的工作重点在于协调阶段任务。参与各个阶段任务的线程数量可以不同。
比如第一阶段有5个线程参与,第二阶段可以有2个线程参与,第三阶段可以有3个线程参与。每个阶段中,线程可以通过register()注册到该阶段,执行完逻辑后,可以使用arriveAndDeregister()取消注册。当发现所有参与注册的线程都到达并取消注册后,就开始下一阶段的任务。
public static void main(String[] args) {
Phaser phaser = new Phaser();
phaser.register();
IntStream.rangeClosed(1, 10).forEach(number -> {
phaser.register();
Thread student = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("阶段1-线程" + number + "完成");
phaser.arriveAndDeregister();
});
student.start();
});
System.out.println("阶段1开始,时间" + getTime());
//阻塞
phaser.arriveAndAwaitAdvance();
System.out.println("阶段1完毕,时间" + getTime());
//开始新的phase
IntStream.rangeClosed(1, 3).forEach(number -> {
phaser.register();
Thread teacher = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("阶段2-线程" + number + "完成");
phaser.arriveAndDeregister();
});
teacher.start();
});
System.out.println("阶段2开始,时间" + getTime());
//阻塞
phaser.arriveAndAwaitAdvance();
System.out.println("阶段2完毕,时间" + getTime());
//开始新的phase
IntStream.rangeClosed(1, 3).forEach(number -> {
phaser.register();
Thread counsellor = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("阶段3-线程" + number + "完成");
phaser.arriveAndDeregister();
});
counsellor.start();
});
System.out.println("阶段3开始,时间" + getTime());
phaser.arriveAndAwaitAdvance();
System.out.println("阶段3完毕,时间" + getTime());
}
private static String getTime() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date(System.currentTimeMillis()));
}
打印结果:
阶段1开始,时间2020-03-02 02:22:20
阶段1-线程2完成
阶段1-线程3完成
阶段1-线程1完成
阶段1-线程5完成
阶段1-线程4完成
阶段1-线程6完成
阶段1-线程10完成
阶段1-线程7完成
阶段1-线程8完成
阶段1-线程9完成
阶段1完毕,时间2020-03-02 02:22:23
阶段2开始,时间2020-03-02 02:22:23
阶段2-线程2完成
阶段2-线程1完成
阶段2-线程3完成
阶段2完毕,时间2020-03-02 02:22:26
阶段3开始,时间2020-03-02 02:22:26
阶段3-线程2完成
阶段3-线程3完成
阶段3-线程1完成
阶段3完毕,时间2020-03-02 02:22:29