1. 阶段===>不同的阶段,按照不同的阶段来对线程进行不同的执行
  2. 有的线程运行到中间就停了,有的线程会一直运行到最后
  3. 在程序中需要用到分阶段执行,有的怎样……有的怎样……,是好几个线程一起执行的
  4. 真正开发中很少用===>演示程序
  5. 遗传算法会用到===>计算机模拟达尔文的进化论的算法
  6. 有点像先异步,后同步;每个阶段先异步,然后再同步
  7. 之前的栅栏是拦住好多线程的,而现在是拦住特定的线程

结婚场景(好多人参加)

  1. 婚礼分几个阶段:到齐—->吃饭—->离开—->新郎新娘拥抱
  2. 每一个阶段得控制人数===>第一个阶段得人到齐了才能开始;第二阶段所有人都吃饭;第三阶段所有人都离开;只有新郎新娘入洞房
  3. 想正确模拟这个程序,整个过程就得分好几个阶段,必须得上一个阶段的内容都干完事了,才能进入下一个阶段,不能不吃饭直接入洞房
  4. 所有线程都抵达了栅栏的时候(即满足了条件的时候),onAdvance会自动被调用
  5. 如果再有下一个阶段,这些线程就不会再参与了—-> phaser.arriveAndDeregister();
  6. 等着一批的线程结束一起进入下一个阶段—->phaser.arriveAndAwaitAdvance();
  7. 不仅可以**控制栅栏的个数,还可以控制栅栏上等待线程的数量**
  8. CyclicBarrier的升级版:Phaser**从jdk1.7开始有的**
  9. 注册了几个线程;**每一个方法代表一个阶段**
  10. return true;表示所有的阶段都执行结束了—->整个phaser的栅栏组结束了
  11. 原理???
  1. package com.mashibing.juc.c_020;
  2. import java.util.Random;
  3. import java.util.concurrent.Phaser;
  4. import java.util.concurrent.TimeUnit;
  5. public class T09_TestPhaser2 {
  6. static Random r = new Random();
  7. static MarriagePhaser phaser = new MarriagePhaser();
  8. // 封装try……catch……
  9. // 增加代码可读性
  10. static void milliSleep(int milli) {
  11. try {
  12. TimeUnit.MILLISECONDS.sleep(milli);
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. public static void main(String[] args) {
  18. // 注册了7个线程;每一个方法代表一个阶段
  19. phaser.bulkRegister(7);
  20. for(int i=0; i<5; i++) {
  21. new Thread(new Person("p" + i)).start();
  22. }
  23. new Thread(new Person("新郎")).start();
  24. new Thread(new Person("新娘")).start();
  25. }
  26. static class MarriagePhaser extends Phaser {
  27. // 重写 前进===>到了栅栏满足条件的情况下,onAdvance会自动被调用
  28. // 第一个参数为当前是第几个阶段,第二个参数是当前阶段由哪些人参加(哪些线程参与了这个阶段--->栅栏推到之后还剩多少人参与当前阶段!)
  29. // return true;的时候整个过程就结束了(所有线程结束了),整个phaser的栅栏组就结束了
  30. @Override
  31. protected boolean onAdvance(int phase, int registeredParties) {
  32. switch (phase) {
  33. case 0:
  34. System.out.println("所有人到齐了!" + registeredParties);
  35. System.out.println();
  36. return false;
  37. case 1:
  38. System.out.println("所有人吃完了!" + registeredParties);
  39. System.out.println();
  40. return false;
  41. case 2:
  42. System.out.println("所有人离开了!" + registeredParties);
  43. System.out.println();
  44. return false;
  45. case 3:
  46. System.out.println("婚礼结束!新郎新娘抱抱!" + registeredParties);
  47. return true;
  48. default:
  49. return true;
  50. }
  51. }
  52. }
  53. static class Person implements Runnable {
  54. String name;
  55. public Person(String name) {
  56. this.name = name;
  57. }
  58. public void arrive() {
  59. milliSleep(r.nextInt(1000));
  60. System.out.printf("%s 到达现场!\n", name);
  61. phaser.arriveAndAwaitAdvance();
  62. }
  63. public void eat() {
  64. milliSleep(r.nextInt(1000));
  65. System.out.printf("%s 吃完!\n", name);
  66. phaser.arriveAndAwaitAdvance();
  67. }
  68. public void leave() {
  69. milliSleep(r.nextInt(1000));
  70. System.out.printf("%s 离开!\n", name);
  71. phaser.arriveAndAwaitAdvance();
  72. }
  73. private void hug() {
  74. if(name.equals("新郎") || name.equals("新娘")) {
  75. milliSleep(r.nextInt(1000));
  76. System.out.printf("%s 洞房!\n", name);
  77. phaser.arriveAndAwaitAdvance();
  78. } else {
  79. // 解除线程,不再继续向下了
  80. // 如果再有下一个阶段,这些线程就不会再参与了
  81. phaser.arriveAndDeregister();
  82. //phaser.register()
  83. }
  84. }
  85. @Override
  86. public void run() {
  87. arrive();
  88. eat();
  89. leave();
  90. hug();
  91. }
  92. }
  93. }