并发编程中,如果线程任务时分阶段进行的,那么使用Phaser来实现是很好的选择。
假设有个需求,小红,小毛,小明3人要聚个会,他们要先一起在烧烤店吃烧烤,然后再一起去喝奶茶聊聊天,最后感觉累了才回家。这里3个人就是3个不同的线程,同时做某些事,大家都做好了再继续做下一件事。
先看下Phaser类的一些方法
//默认的构造方法,初始化注册的线程数量为0,可以动态注册
Phaser();
//指定了线程数量的构造方法
Phaser(int parties);
//添加一个注册者
register();
//添加指定数量的注册者
bulkRegister(int parties);
// 到达屏障点直接执行,等待不用其他的线程
arrive();
//到达屏障点后,也必须等待其他所有注册者到达这个屏障点才能继续下一步
arriveAndAwaitAdvance();
//到达屏障点,把自己注销了,不用等待其他的注册者到达
arriveAndDeregister();
//多个线程达到注册点之后,会回调这个方法,可以做一些逻辑的补充
onAdvance(int phase, int registeredParties);
示例代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Phaser;
public class SpringbootApplication {
//自定义一个移相器来自定义输出
static class MyPhaser extends Phaser {
@Override
protected boolean onAdvance(int phase, int registeredParties) {
switch (phase) {
case 0:
System.out.println("所有人都到达了烧烤店,开始点菜");
return false;
case 1:
System.out.println("到达奶茶店,一起喝奶茶聊聊天");
return false;
case 2:
System.out.println("喝完奶茶,各自打车回家");
return true;
default:
return true;
}
}
}
//构建一个线程任务
static class DoSomeThing implements Runnable {
private Phaser phaser;
private String name;
@Override
public void run() {
System.out.println(name + "打车去烧烤店");
phaser.arriveAndAwaitAdvance();
System.out.println(name + "吃烧烤吃饱了");
phaser.arriveAndAwaitAdvance();
System.out.println(name + "奶茶喝完了,话也聊完了");
phaser.arriveAndAwaitAdvance();
}
public DoSomeThing(Phaser phaser, String name) {
this.phaser = phaser;
this.name = name;
//添加一个注册者
phaser.register();
}
}
public static void main(String[] args) throws Exception {
MyPhaser myPhaser = new MyPhaser();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(new DoSomeThing(myPhaser, "小明"));
executorService.submit(new DoSomeThing(myPhaser, "小红"));
executorService.submit(new DoSomeThing(myPhaser, "小毛"));
executorService.shutdown();
}
}
运行结果如下:
可以发现,有了Phaser的配合,线程任务的分阶段任务就能够有条不紊的按需执行了。
总结
这个类的实现是很复杂的,但是如果不研究它的具体实现,了解下它的存在和如何使用,开发中应用是够了,哪有那么多时间,什么东西都研究,还是要取舍的。