Phaser 是什么
pahser是一个可以重复使用的同步屏障。应用包括但不限于于如下场景:每个线程有n个方法,希望在一部分线程的第i个方法执行完成后,再统一调用第i+1个方法。可以在一组线程同时注册的时候,设置一个阈值,当线程数到达数量达到阈值后,由phaser调用下一个方法。可以通过注册和注销修改计数器的大小。
Phaser主要方法
Phaser() 构造方法,创建一个移项器。
bulkRegister(int parties),为同步屏障增加计数器的计数。
awaitAdvance(int phase),当前步骤到达,等待其他线程到达。
arriveAndDeregister(),
到达这个移相器并从其中注销,而无需等待别人到达。
register(),
添加一个新的unririved party到这个移相器。
Phaser代码演示
1 static Random r= new Random(); 2 static MarriagePhaser phaser = new MarriagePhaser(); 3 static void milliSleep(int milli) { 4 try { 5 TimeUnit.MILLISECONDS.sleep(milli); 6 } catch (InterruptedException e) { 7 e.printStackTrace(); 8 } 9 } 10 11 public static void main(String[] args) { 12 phaser.bulkRegister(7); 13 for (int i = 0; i < 5; i++) { 14 final int nameIndex=i; 15 new Thread(new Person("客人"+nameIndex) 16 ).start(); 17 } 18 new Thread(new Person("新郎") 19 ).start(); 20 new Thread(new Person("新娘") 21 ).start(); 22 } 23 static class Person implements Runnable{ 24 String name; 25 public Person(String name){ 26 this.name = name; 27 } 28 public void arrive() { 29 milliSleep(r.nextInt(1000)); 30 System.out.printf("%s 到达现场! ",name); 31 phaser.arriveAndAwaitAdvance(); 32 } 33 34 public void eat() { 35 milliSleep(r.nextInt(1000)); 36 System.out.printf("%s 吃完! ",name); 37 phaser.arriveAndAwaitAdvance(); 38 } 39 public void leave() { 40 milliSleep(r.nextInt(1000)); 41 System.out.printf("%s 离开! ",name); 42 phaser.arriveAndAwaitAdvance(); 43 } 44 public void hug() { 45 if (name.equals("新郎")||name.equals("新娘")) { 46 milliSleep(r.nextInt(1000)); 47 System.out.printf("%s 洞房! ",name); 48 phaser.arriveAndAwaitAdvance(); 49 50 }else { 51 // 注销 52 phaser.arriveAndDeregister(); 53 // phaser.register(); 把当前线程加入进去 54 } 55 } 56 @Override 57 public void run() { 58 arrive(); 59 eat(); 60 leave(); 61 hug(); 62 63 } 64 65 66 } 67 static class MarriagePhaser extends Phaser{ 68 @Override 69 protected boolean onAdvance(int phas,int registeredParties) { 70 switch (phas) { 71 case 0: 72 System.out.println("所以人到齐了!"+registeredParties); 73 return false; 74 case 1: 75 System.out.println("所以人吃完了!"+registeredParties); 76 return false; 77 case 2: 78 System.out.println("所以人离开了"+registeredParties); 79 System.out.println("婚礼结束"+registeredParties); 80 return false; 81 case 3: 82 System.out.println("洞房完成"+registeredParties); 83 84 return true; 85 86 default: 87 return true; 88 } 89 } 90 } 91
注:代码来源:马士兵公开课