Phaser用法详解
用Phaser替代CyclicBarrier和CountDownLatch
Phaser相比CyclicBarrier和CountDownLatch功能更强大,包括它两的所有功能。
用Phaser替代CyclicBarrier
public class PhaserTest1 {
public static void main(String[] args) {
Phaser phaser = new Phaser();
for (int i = 0; i < 5; i++) {
new Task(phaser).start();
}
//main 线程自己也注册进来
phaser.register();
//等待其他线程都完成
phaser.arriveAndAwaitAdvance();
System.out.println(" all thread end");
}
}
class Task extends Thread{
private final Phaser phaser;
Task(Phaser phaser) {
this.phaser = phaser;
//自己 添加进来 添加到位象器中
this.phaser.register();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " start ... " );
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
//到达 并且等待前行
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + " end ... " );
}
}
可以看到
用Phaser替代CountDownLatch
重复计数以及所有线程都准备好
public static void main(String[] args) {
// 初始化计数器
Phaser phaser = new Phaser(5);
for (int i = 0; i < 5; i++) {
new Sports(phaser, i + 1).start();
}
//main 线程自己也注册进来
phaser.register();
// 注册多个
//phaser.bulkRegister(1);
//等待其他线程都完成
phaser.arriveAndAwaitAdvance();
System.out.println(" all thread end");
}
static class Sports extends Thread {
private final Phaser phaser;
private final int no;
public Sports(Phaser phaser, int no) {
this.phaser = phaser;
this.no = no;
}
@Override
public void run() {
System.out.println(" 第 " + no + " 开始 run ... ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 计数 每次都0开始往上计数
System.out.println(" 查看 run count 计数 ---> " + phaser.getPhase() );
System.out.println(" 第 " + no + " 开始 run end ... ");
phaser.arriveAndAwaitAdvance(); // 等待所有线程都执行完成 再执行下面的任务
System.out.println(" 第 " + no + " 开始 swing ... ");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" 查看 swing count 计数 ---> " + phaser.getPhase() );
System.out.println(" 第 " + no + " 开始 swing end ... ");
phaser.arriveAndAwaitAdvance();
}
}
运行结果
第 1 开始 run …
第 4 开始 run …
第 3 开始 run …
第 2 开始 run …
第 5 开始 run …
查看 run count 计数 —> 0
查看 run count 计数 —> 0
查看 run count 计数 —> 0
查看 run count 计数 —> 0
查看 run count 计数 —> 0
第 4 开始 run end …
第 2 开始 run end …
第 5 开始 run end …
第 3 开始 run end …
第 1 开始 run end …
第 3 开始 swing …
第 1 开始 swing …
第 4 开始 swing …
第 2 开始 swing …
第 5 开始 swing …
all thread end
查看 swing count 计数 —> 1
第 4 开始 swing end …
查看 swing count 计数 —> 1
查看 swing count 计数 —> 1
第 3 开始 swing end …
查看 swing count 计数 —> 1
第 5 开始 swing end …
查看 swing count 计数 —> 1
第 2 开始 swing end …
第 1 开始 swing end …
Phaser新特性
动态增加计数,类似 运动员比赛,中途有人退场
// 注册一个
register()
// 注册多个
bulkRegister(int parties)
// 解除注册
arriveAndDeregister()
Phaser phaser = new Phaser();
for (int i = 0; i < 5; i++) {
new Task(phaser).start();
}
//main 线程自己也注册进来
//phaser.register();
//去除一个
phaser.arriveAndDeregister();
//等待其他线程都完成
phaser.arriveAndAwaitAdvance();
System.out.println(" all thread end");