- 阶段===>不同的阶段,按照不同的阶段来对线程进行不同的执行
- 有的线程运行到中间就停了,有的线程会一直运行到最后
- 在程序中需要用到分阶段执行,有的怎样……有的怎样……,是好几个线程一起执行的
- 真正开发中很少用===>演示程序
- 遗传算法会用到===>计算机模拟达尔文的进化论的算法
- 有点像先异步,后同步;每个阶段先异步,然后再同步
- 之前的栅栏是拦住好多线程的,而现在是拦住特定的线程
结婚场景(好多人参加)
- 婚礼分几个阶段:到齐—->吃饭—->离开—->新郎新娘拥抱
- 每一个阶段得控制人数===>第一个阶段得人到齐了才能开始;第二阶段所有人都吃饭;第三阶段所有人都离开;只有新郎新娘入洞房
- 想正确模拟这个程序,整个过程就得分好几个阶段,必须得上一个阶段的内容都干完事了,才能进入下一个阶段,不能不吃饭直接入洞房
- 所有线程都抵达了栅栏的时候(即满足了条件的时候),onAdvance会自动被调用
- 如果再有下一个阶段,这些线程就不会再参与了—-> phaser.arriveAndDeregister();
- 等着一批的线程结束一起进入下一个阶段—->phaser.arriveAndAwaitAdvance();
- 不仅可以**控制栅栏的个数,还可以控制栅栏上等待线程的数量**
- CyclicBarrier的升级版:Phaser**从jdk1.7开始有的**
- 注册了几个线程;**每一个方法代表一个阶段**
- return true;表示所有的阶段都执行结束了—->整个phaser的栅栏组结束了
- 原理???
package com.mashibing.juc.c_020;
import java.util.Random;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
public class T09_TestPhaser2 {
static Random r = new Random();
static MarriagePhaser phaser = new MarriagePhaser();
// 封装try……catch……
// 增加代码可读性
static void milliSleep(int milli) {
try {
TimeUnit.MILLISECONDS.sleep(milli);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 注册了7个线程;每一个方法代表一个阶段
phaser.bulkRegister(7);
for(int i=0; i<5; i++) {
new Thread(new Person("p" + i)).start();
}
new Thread(new Person("新郎")).start();
new Thread(new Person("新娘")).start();
}
static class MarriagePhaser extends Phaser {
// 重写 前进===>到了栅栏满足条件的情况下,onAdvance会自动被调用
// 第一个参数为当前是第几个阶段,第二个参数是当前阶段由哪些人参加(哪些线程参与了这个阶段--->栅栏推到之后还剩多少人参与当前阶段!)
// return true;的时候整个过程就结束了(所有线程结束了),整个phaser的栅栏组就结束了
@Override
protected boolean onAdvance(int phase, int registeredParties) {
switch (phase) {
case 0:
System.out.println("所有人到齐了!" + registeredParties);
System.out.println();
return false;
case 1:
System.out.println("所有人吃完了!" + registeredParties);
System.out.println();
return false;
case 2:
System.out.println("所有人离开了!" + registeredParties);
System.out.println();
return false;
case 3:
System.out.println("婚礼结束!新郎新娘抱抱!" + registeredParties);
return true;
default:
return true;
}
}
}
static class Person implements Runnable {
String name;
public Person(String name) {
this.name = name;
}
public void arrive() {
milliSleep(r.nextInt(1000));
System.out.printf("%s 到达现场!\n", name);
phaser.arriveAndAwaitAdvance();
}
public void eat() {
milliSleep(r.nextInt(1000));
System.out.printf("%s 吃完!\n", name);
phaser.arriveAndAwaitAdvance();
}
public void leave() {
milliSleep(r.nextInt(1000));
System.out.printf("%s 离开!\n", name);
phaser.arriveAndAwaitAdvance();
}
private void hug() {
if(name.equals("新郎") || name.equals("新娘")) {
milliSleep(r.nextInt(1000));
System.out.printf("%s 洞房!\n", name);
phaser.arriveAndAwaitAdvance();
} else {
// 解除线程,不再继续向下了
// 如果再有下一个阶段,这些线程就不会再参与了
phaser.arriveAndDeregister();
//phaser.register()
}
}
@Override
public void run() {
arrive();
eat();
leave();
hug();
}
}
}