目标:使用Phaser构造简单阶段任务反馈
Phaser
- 移相器:可重用的同步屏障,功能比CyclicBarrier与CountDownLatch更加灵活。
- onAdvance:全部线程执行完毕后会进行调用,每次都会使参数phase的值+1,可用于判断阶段。返回true的话会结束phase。
- register():线程进行注册,实际是进行一次信号+1。
- arriveAndAwaitAdvance():阻塞并等待其他线程到达,等信号值达到一定值时会通过。
- arriveAndDeregister():非阻塞,到达后直接注销一个信号。
代码:
package com.miracle.study.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Phaser;
/**
* @author Miracle
* @date 2021/4/14 21:08
*/
public class PhaserTest {
/**
* 集成phaser重写onAdvance
*/
static class TaskPhaser extends Phaser{
/**
* 每一次全部线程到达都会导致phase的值+1。
* @param phase
* @param registeredParties
* @return
*/
@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:
// 返回true就会使这个phaser停止了
return true;
}
}
}
/**
* 线程任务类
*/
static class Work implements Runnable{
private Phaser phaser;
private String name;
public Work(Phaser phaser, String name){
this.phaser = phaser;
this.name = name;
}
@Override
public void run() {
phaser.register();
try {
System.out.println(name + "第一阶段进行中");
Thread.sleep(100);
// 等待其他线程完成任务
phaser.arriveAndAwaitAdvance();
System.out.println(name + "第二阶段进行中");
Thread.sleep(100);
// 等待其他线程完成任务
phaser.arriveAndAwaitAdvance();
System.out.println(name + "第三阶段进行中");
Thread.sleep(100);
// 等待其他线程完成任务
phaser.arriveAndDeregister();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
TaskPhaser taskPhaser = new TaskPhaser();
// 主线程先注册入phaser,保证所有线程完成后,然后进行注销,避免出现有的线程还没注册,就有一些线程完成第一阶段代码。
taskPhaser.register();
for (int i = 0; i < 10; i++){
executorService.execute(new Work(taskPhaser, "task" + i));
}
// 等待并注销
taskPhaser.arriveAndDeregister();
Thread.sleep(2000);
// 看taskPhaser是否已关闭
System.out.println(taskPhaser.isTerminated());
// 强制结束phaser
taskPhaser.forceTermination();
System.out.println(taskPhaser.isTerminated());
}
}
参考
https://blog.csdn.net/liuyu973971883/article/details/107917079