参考博客:https://blog.csdn.net/tianshi_kco/article/details/52975468
总结
java7中引入了一种新的可重复使用的同步屏障,称为移相器
Phaser
,Phaser
相比较于CyclicBarrier
和CountDownLatch
更加灵活。特性一:
CountDownLatch
、CyclicBarrier
只适用于固定数量的参与者,而Phaser
适用于可变数目的屏障。特性二:移相器
Phaser
可能是分层的,这允许你以树形结构来安排移相器Phaser
以减少竞争。特性三:移相器
Phaser
使用独立的对象可以监视移相器Phaser
的当前状态,监视器可以查询注册到移相器Phaser
的参与者的数量,以及已经到达和还没有到达某个特定相数的参与者的数量。
特性一代码演示 代替CyclicBarrier
CyclicBarrier的await()方法可以直接用Phaser的arriveAndAwaitAdvance()方法替代。
// 3名玩家一起玩游戏,先玩跳舞机,再玩投篮,最后玩赛车。
public class PhaserDemo {
public static void main(String[] args) {
Phaser phaser = new Phaser(3);
PhaserPlayer player = new PhaserPlayer(phaser);
for(int i = 0;i<3;i++){
new Thread(player).start();
}
}
static class PhaserPlayer implements Runnable{
Phaser phaser;
public PhaserPlayer(Phaser phaser) {
this.phaser = phaser;
}
public void adapterGame(String name) {
long startTime = System.currentTimeMillis();
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+"使用:"+(endTime-startTime)+"毫秒玩了"+name+"游戏!");
phaser.arriveAndAwaitAdvance();
}
@Override
public void run() {
adapterGame("跳舞机");
adapterGame("投篮");
adapterGame("赛车");
}
}
}
运行结果
Thread-0使用:2毫秒玩了跳舞机游戏!
Thread-2使用:2毫秒玩了跳舞机游戏!
Thread-1使用:2毫秒玩了跳舞机游戏!
Thread-0使用:1毫秒玩了投篮游戏!
Thread-1使用:1毫秒玩了投篮游戏!
Thread-2使用:1毫秒玩了投篮游戏!
Thread-2使用:2毫秒玩了赛车游戏!
Thread-1使用:2毫秒玩了赛车游戏!
Thread-0使用:2毫秒玩了赛车游戏!
Process finished with exit code 0
特性一代码演示 代替CountdownLatch
CountDownLatch主要使用的有2个方法:
await()方法,可以使线程进入等待状态,在Phaser中,与之对应的方法是awaitAdvance(int n);
countDown(),使计数器减一,当计数器为0时所有等待的线程开始执行,在Phaser中,与之对应的方法是arrive()。
public class PhaserDemo2 {
public static void main(String[] args) {
Phaser phaser = new Phaser(3);
ThreadDemo threadDemo = new ThreadDemo(phaser);
for(int i = 0;i<3;i++){
new Thread(threadDemo).start();
}
phaser.awaitAdvance(phaser.getPhase());
System.out.println("都执行完了"+phaser.getPhase());
}
static class ThreadDemo implements Runnable{
Phaser phaser;
public ThreadDemo(Phaser phaser) {
this.phaser = phaser;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行arrive()"+phaser.getPhase());
phaser.arrive();
}
}
}
运行结果
Thread-2执行arrive()0
Thread-0执行arrive()0
Thread-1执行arrive()0
都执行完了1
Process finished with exit code 0
特性二代码演示
移相器Phaser
可能是分层的,这允许你以树形结构来安排移相器Phaser
以减少竞争。
// TODO
特性三代码演示
// TODO
phaser.getPhase()
初始值为0,如果全部线程到达集合点这个Phase
+1,如果phaser.getPhase()
达到Integer的最大值,这重新清空为0,在这里表示第几次集合了
phaser.arriveAndDeregister();
表示这个线程到达集合点,就离开这个团体
phaser.arriveAndAwaitAdvance();
表示这个线程在到某个达集合点,在等待其他线程
phaser.bulkRegister(friendNum);
表示这个线程在某个集合点遇到了friendNum
个线程,他们要加入这个团体。