Phaser用法详解

129 阅读1分钟

Phaser用法详解

用Phaser替代CyclicBarrier和CountDownLatch

Phaser相比CyclicBarrier和CountDownLatch功能更强大,包括它两的所有功能。

用Phaser替代CyclicBarrier

public class PhaserTest1 {

    public static void main(String[] args) {


        Phaser phaser  = new Phaser();


        for (int i = 0; i < 5; i++) {
            new Task(phaser).start();
        }

        //main 线程自己也注册进来
        phaser.register();

        //等待其他线程都完成
        phaser.arriveAndAwaitAdvance();

        System.out.println(" all  thread  end");

    }
}

class Task extends Thread{

    private final Phaser phaser;

    Task(Phaser phaser) {
        this.phaser = phaser;
        //自己 添加进来 添加到位象器中
        this.phaser.register();
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "  start ... " );
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //到达 并且等待前行
        phaser.arriveAndAwaitAdvance();

        System.out.println(Thread.currentThread().getName() + "  end ... " );
    }
}

可以看到
在这里插入图片描述

用Phaser替代CountDownLatch

重复计数以及所有线程都准备好


    public static void main(String[] args) {


        // 初始化计数器
        Phaser phaser = new Phaser(5);

        for (int i = 0; i < 5; i++) {
            new Sports(phaser, i + 1).start();
        }

        //main 线程自己也注册进来
        phaser.register();
       
        // 注册多个
        //phaser.bulkRegister(1);

        //等待其他线程都完成
        phaser.arriveAndAwaitAdvance();

        System.out.println(" all  thread  end");

    }

    static class Sports extends Thread {


        private final Phaser phaser;
        private final int no;

        public Sports(Phaser phaser, int no) {
            this.phaser = phaser;
            this.no = no;
        }

        @Override
        public void run() {

            System.out.println(" 第 " + no + " 开始 run ... ");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 计数 每次都0开始往上计数
            System.out.println(" 查看 run  count 计数 --->  " + phaser.getPhase() );
            System.out.println(" 第 " + no + " 开始 run end  ... ");
            phaser.arriveAndAwaitAdvance();  // 等待所有线程都执行完成  再执行下面的任务
            
            System.out.println(" 第 " + no + " 开始 swing ... ");
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(" 查看 swing  count 计数 --->  " + phaser.getPhase() );
            System.out.println(" 第 " + no + " 开始 swing end  ... ");
            phaser.arriveAndAwaitAdvance();


        }
    }

运行结果

第 1 开始 run …
第 4 开始 run …
第 3 开始 run …
第 2 开始 run …
第 5 开始 run …
查看 run count 计数 —> 0
查看 run count 计数 —> 0
查看 run count 计数 —> 0
查看 run count 计数 —> 0
查看 run count 计数 —> 0
第 4 开始 run end …
第 2 开始 run end …
第 5 开始 run end …
第 3 开始 run end …
第 1 开始 run end …
第 3 开始 swing …
第 1 开始 swing …
第 4 开始 swing …
第 2 开始 swing …
第 5 开始 swing …
all thread end
查看 swing count 计数 —> 1
第 4 开始 swing end …
查看 swing count 计数 —> 1
查看 swing count 计数 —> 1
第 3 开始 swing end …
查看 swing count 计数 —> 1
第 5 开始 swing end …
查看 swing count 计数 —> 1
第 2 开始 swing end …
第 1 开始 swing end …

Phaser新特性

动态增加计数,类似 运动员比赛,中途有人退场
// 注册一个
register()
// 注册多个
bulkRegister(int parties)
// 解除注册
arriveAndDeregister()

   Phaser phaser  = new Phaser();


        for (int i = 0; i < 5; i++) {
            new Task(phaser).start();
        }

        //main 线程自己也注册进来
        //phaser.register();
        //去除一个
        phaser.arriveAndDeregister();
        //等待其他线程都完成
        phaser.arriveAndAwaitAdvance();

        System.out.println(" all  thread  end");