Phaser阶段器
目录
Phaser概念
Phaser表示“阶段器”,用来解决控制多个线程分阶段共同完成大型任务的情景问题。也就是说,事情一趟流程走下来,可以分为若干个阶段,每个阶段的工作都需要注册该阶段的N个人来干。每人干自己的活,手脚快的呢,就干好到达第一阶段的屏障前等待手脚慢的人干完活后也到达第一阶段屏障,...直至注册该阶段的N个人都各自干完了一阶段期间内的活,都到达了第一阶段屏障,第一阶段屏障打开,准许这N个人通行,继续进行下一阶段...周而复始...直至所有阶段都干完,结束。
其作用相比CountDownLatch和CyclicBarrier更加灵活。
Phaser内有2个重要状态:phase和party,有一个重要方法:onAdvance()
- phase阶段,初值为0,当所有的线程执行完本轮任务,phase值自动加1,phase放行,线程可进入到下一阶段。
- party注册线程,party=3就意味着要在该阶段注册3个线程,Phaser对象当前管理着3个线程。
- boolean onAdvance(int phase, int registeredParties)方法,经常需要被重载,此方法有2个作用:
当每一个阶段执行完毕,此方法会被调用,相当于CyclicBarrier的barrierAction。
当此方法返回true时,意味着Phaser被终止,因此重载此方法时将返回值是否设置为true来决定是否终止所有线程。
下面举例业务场景:
仓库来了一货车的货物要入库,货物很多,需要N个人(多线程)来干,干活有快有慢的,手脚快的人多劳多得
第一阶段:注册了3人,每人都从车上卸下货物,3人将所有的货物都卸货完毕后,得以通过第一阶段屏障,进入下一阶段
第二阶段:注册了3人,每人都把货物码放托盘,3人将所有的货物都码托完毕后,得以通过第二阶段屏障,进入下一阶段
第三阶段:注册了3人,每人都把码盘入仓存放,3人将所有的货物都入仓完毕后,得以通过第三阶段屏障,进入下一阶段
结束
Phaser示例1
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.atomic.*;
//任务
class TaskWms implements Runnable
{
private Phaser phase;
public TaskWms(Phaser phase){
this.phase = phase ;
}
public void run(){
/**
* 初始
*/
String tName = Thread.currentThread().getName();
/**
* 第0段:卸货
*/
try{
long time = (long)(Math.random() * 5000);
Thread.sleep(time);
System.out.println(tName+"卸货】耗时is:["+time+"]");
}catch(InterruptedException e){}
phase.arriveAndAwaitAdvance();//每个线程都到达后,通过当前阶段,调用onAdvance()方法.
/**
* 第1段:码托
*/
try{
long time = (long)(Math.random() * 5000);
Thread.sleep(time);
System.out.println(tName+"码托】耗时is:["+time+"]");
}catch(InterruptedException e){}
phase.arriveAndAwaitAdvance();
/**
* 第2段:入库
*/
try{
long time = (long)(Math.random() * 5000);
Thread.sleep(time);
System.out.println(tName+"入库】耗时is:["+time+"]");
}catch(InterruptedException e){}
phase.arriveAndAwaitAdvance();
/**
* 结束:结账领工钱
*/
System.out.println(tName+"结账领工钱...");
phase.arriveAndDeregister();
}
}
/**
* 自定义阶段器:重载onAdvance()方法:可表达每阶段结束后的响应
* 注意Phaser阶段器是从零开始的,
* 首次调用onAdvance()时,刚刚越过的阶段屏障的值为0
*/
class MyPhaser extends Phaser
{
public boolean onAdvance(int p, int party){
switch(p){
case 0:
System.out.println("...卸货完毕!\n\r");
return false;
case 1:
System.out.println("...码托完毕!\n\r");
return false;
case 2:
System.out.println("...入库完毕!\n\r");
return false;
case 3:
System.out.println("\n\r大家都已记账结算工资!\n\r");
return true;
default:
return true;
}
}
}
/**
* 测试
*/
public class PhaserTest {
public static void main(String[] args) {
MyPhaser phase = new MyPhaser();
Thread[] threads = new Thread[3];
for (int i = 0; i < 3; i++) {
TaskWms task = new TaskWms(phase);