- 阶段===>不同的阶段,按照不同的阶段来对线程进行不同的执行
- 有的线程运行到中间就停了,有的线程会一直运行到最后
- 在程序中需要用到分阶段执行,有的怎样……有的怎样……,是好几个线程一起执行的
- 真正开发中很少用===>演示程序
- 遗传算法会用到===>计算机模拟达尔文的进化论的算法
- 有点像先异步,后同步;每个阶段先异步,然后再同步
- 之前的栅栏是拦住好多线程的,而现在是拦住特定的线程
结婚场景(好多人参加)
- 婚礼分几个阶段:到齐—->吃饭—->离开—->新郎新娘拥抱
- 每一个阶段得控制人数===>第一个阶段得人到齐了才能开始;第二阶段所有人都吃饭;第三阶段所有人都离开;只有新郎新娘入洞房
- 想正确模拟这个程序,整个过程就得分好几个阶段,必须得上一个阶段的内容都干完事了,才能进入下一个阶段,不能不吃饭直接入洞房
- 所有线程都抵达了栅栏的时候(即满足了条件的时候),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(); } }}