当前位置: 首页 > 工具软件 > Phaser > 使用案例 >

Phaser基本理解和用法

景靖琪
2023-12-01

Phaser

参考博客:https://blog.csdn.net/tianshi_kco/article/details/52975468

总结

java7中引入了一种新的可重复使用的同步屏障,称为移相器Phaser,Phaser相比较于CyclicBarrierCountDownLatch更加灵活。

特性一:CountDownLatchCyclicBarrier只适用于固定数量的参与者,而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个线程,他们要加入这个团体。

 类似资料: