主要并发工具类-Phaser的使用

Phaser:阶段器。

官方文档中这样描述:

可重用的同步屏障,功能类似于CyclicBarrier和CountDownLatch,但是更为灵活。
与其他屏障不同,在Phaser上进行同步的已注册的party的数量会随时间变化。任务可以随时注册(使用register()或bulkRegister()),以及可以在任何到达的时候注销(使用arriveAndDeregister())。

该类的工作重点在于协调阶段任务。参与各个阶段任务的线程数量可以不同。

比如第一阶段有5个线程参与,第二阶段可以有2个线程参与,第三阶段可以有3个线程参与。每个阶段中,线程可以通过register()注册到该阶段,执行完逻辑后,可以使用arriveAndDeregister()取消注册。当发现所有参与注册的线程都到达并取消注册后,就开始下一阶段的任务。

    public static void main(String[] args) {
        Phaser phaser = new Phaser();
        phaser.register();
        IntStream.rangeClosed(1, 10).forEach(number -> {
            phaser.register();
            Thread student = new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("阶段1-线程" + number + "完成");
                phaser.arriveAndDeregister();
            });
            student.start();
        });

        System.out.println("阶段1开始,时间" + getTime());
        //阻塞
        phaser.arriveAndAwaitAdvance();
        System.out.println("阶段1完毕,时间" + getTime());
        //开始新的phase
        IntStream.rangeClosed(1, 3).forEach(number -> {
            phaser.register();
            Thread teacher = new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("阶段2-线程" + number + "完成");
                phaser.arriveAndDeregister();
            });
            teacher.start();
        });
        System.out.println("阶段2开始,时间" + getTime());
        //阻塞
        phaser.arriveAndAwaitAdvance();
        System.out.println("阶段2完毕,时间" + getTime());
        //开始新的phase
        IntStream.rangeClosed(1, 3).forEach(number -> {
            phaser.register();
            Thread counsellor = new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("阶段3-线程" + number + "完成");
                phaser.arriveAndDeregister();
            });
            counsellor.start();
        });
        System.out.println("阶段3开始,时间" + getTime());
        phaser.arriveAndAwaitAdvance();
        System.out.println("阶段3完毕,时间" + getTime());
    }
    
    private static String getTime() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                .format(new Date(System.currentTimeMillis()));
    }

打印结果:

阶段1开始,时间2020-03-02 02:22:20
阶段1-线程2完成
阶段1-线程3完成
阶段1-线程1完成
阶段1-线程5完成
阶段1-线程4完成
阶段1-线程6完成
阶段1-线程10完成
阶段1-线程7完成
阶段1-线程8完成
阶段1-线程9完成
阶段1完毕,时间2020-03-02 02:22:23
阶段2开始,时间2020-03-02 02:22:23
阶段2-线程2完成
阶段2-线程1完成
阶段2-线程3完成
阶段2完毕,时间2020-03-02 02:22:26
阶段3开始,时间2020-03-02 02:22:26
阶段3-线程2完成
阶段3-线程3完成
阶段3-线程1完成
阶段3完毕,时间2020-03-02 02:22:29
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.使用示例 结果: 2.官方文档 可重用的同步barrier,功能类似于CyclicBarrier和CountD...
    王侦阅读 2,773评论 0 3
  • 1. 等待多线程完成的CountDownLatch 简介 CountDownLatch 允许一个或多个线程等待其他...
    xlesterx阅读 1,580评论 0 0
  • java多线程编程中为了满足一些应用场景往往需要对线程进行调度,jdk提供了多种调度方法,接下来我们一一来举例说明...
    探索者_逗你玩儿阅读 5,952评论 0 4
  • 白天和晚上是我们每天都在经历的,那我们把白天比作阳即晚上就是阴。运用到生活上也是一样万事万物都有阴有阳、分...
    帅汉卿阅读 1,648评论 0 2
  • 明显的抗拒来实验室 想到这个场所 这里的空气 和要面对的人 就感到绝望 想到要在这里度过白天 就感到可怕 但是还要...
    与晖阅读 1,306评论 0 0

友情链接更多精彩内容