面试官: Phaser有了解过吗?说说看

简介: 面试官: Phaser有了解过吗?说说看

前言

目前正在出一个Java多线程专题长期系列教程,从入门到进阶含源码解读, 篇幅会较多, 喜欢的话,给个关注❤️ ~


Java提供了一些非常好用的并发工具类,不需要我们重复造轮子,本节我们讲解Phaser,一起来看下吧~


Phaser

Phaser又称“阶段器”,用来解决多线程分阶段任务的场景。它与CountDownLatch和CyclicBarrier类似,都是等待一组线程完成工作后再执行下一步。但CountDownLatch和CyclicBarrier中不能动态的配置parties,而Phaser可以动态注册,相对而言更加的灵活。


常用方法

  • int register() 动态添加一个parties
  • int bulkRegister(int parties) 动态添加多个parties
  • int getRegisteredParties() 获取当前的parties数
  • int arriveAndAwaitAdvance() 到达并等待其他线程到达
  • int arriveAndDeregister() 到达并注销该parties,这个方法不会使线程阻塞
  • int arrive() 到达,但不会使线程阻塞
  • int awaitAdvance(int phase) 等待前行,可阻塞也可不阻塞,判断条件为phase,如果相等则阻塞
  • int awaitAdvanceInterruptibly(int phase) 该方法与awaitAdvance类似,唯一不一样的就是它可以进行打断。
  • int awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit) 同上
  • int getArrivedParties() 获取当前到达的parties数
  • int getUnarrivedParties() 获取当前未到达的parties数
  • int getPhase() 获取当前属于第几阶段,默认从0开始,最大为integer的最大值
  • boolean isTerminated() 判断当前phaser是否关闭
  • void forceTermination()  强制关闭当前phaser


示例

基本上把能用到的方法都给大家介绍了,下面我们通过一个例子实际体验一下:

public class PhaserTest {
    public static void main(String[] args) {
        Phaser phaser = new Phaser(10);
        for (int i=0; i<10; i++){
            new Thread(() -> {
                try {
                    long millis = System.currentTimeMillis();
                    System.out.println(millis + "--1-->当前处于"+phaser.getPhase()+"阶段");
                    Thread.sleep(1000);
                    // wait
                    phaser.arriveAndAwaitAdvance();
                    System.out.println(millis + "---2--->当前处于"+phaser.getPhase()+"阶段");
                    Thread.sleep(1000);
                    // wait
                    phaser.arriveAndAwaitAdvance();
                    System.out.println(millis + "---3--->当前处于"+phaser.getPhase()+"阶段");
                    Thread.sleep(1000);
                    // wait
                    phaser.arriveAndAwaitAdvance();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        System.out.println("主线程");
    }
}
复制代码


实际输出:

1659925927951--1-->当前处于0阶段
主线程
1659925927951--1-->当前处于0阶段
1659925927951--1-->当前处于0阶段
1659925927950--1-->当前处于0阶段
1659925927951--1-->当前处于0阶段
1659925927951--1-->当前处于0阶段
1659925927951--1-->当前处于0阶段
1659925927951--1-->当前处于0阶段
1659925927950--1-->当前处于0阶段
1659925927951--1-->当前处于0阶段
1659925927951---2--->当前处于1阶段
1659925927950---2--->当前处于1阶段
1659925927951---2--->当前处于1阶段
1659925927950---2--->当前处于1阶段
1659925927951---2--->当前处于1阶段
1659925927951---2--->当前处于1阶段
1659925927951---2--->当前处于1阶段
1659925927951---2--->当前处于1阶段
1659925927951---2--->当前处于1阶段
1659925927951---2--->当前处于1阶段
1659925927951---3--->当前处于2阶段
1659925927951---3--->当前处于2阶段
1659925927950---3--->当前处于2阶段
1659925927951---3--->当前处于2阶段
1659925927950---3--->当前处于2阶段
1659925927951---3--->当前处于2阶段
1659925927951---3--->当前处于2阶段
1659925927951---3--->当前处于2阶段
1659925927951---3--->当前处于2阶段
1659925927951---3--->当前处于2阶段
复制代码

可以看出并不会造成主线程的阻塞,任务也是分阶段去完成的, 其它方法就不一一演示了,大家可以自行操作一下


结束语

本节主要讲解它的一个使用,有兴趣的同学可以看一下它的底层源码实现,相对于前两个要复杂一点,这里就不过多介绍。下一节,给大家讲下Fork/Join框架,关注我,不迷路 ~

相关文章
|
JavaScript 前端开发 API
uniapp的优势与劣势
uniapp的优势与劣势
692 1
|
SQL 消息中间件 分布式计算
如何查看spark与hadoop、kafka、Scala、flume、hive等兼容版本【适用于任何版本】
如何查看spark与hadoop、kafka、Scala、flume、hive等兼容版本【适用于任何版本】
1785 0
如何查看spark与hadoop、kafka、Scala、flume、hive等兼容版本【适用于任何版本】
|
10月前
|
Dart 前端开发 JavaScript
【HarmonyOS 5】鸿蒙跨平台开发方案详解 (三)
学习曲线、工具支持、代码复用率、热重载能力
608 0
|
编解码 API 数据安全/隐私保护
自学HarmonyOS Next记录:实现相册访问功能
最近我决定开发一个鸿蒙App,旨在提供更好的照片管理体验。通过使用PhotoAccessHelper API,我实现了访问、显示和管理设备相册中的照片。过程中遇到了权限不足的问题,通过在config.json中添加权限声明并编写权限检查代码得以解决。此外,我还实现了分页加载和展示照片详细信息等功能,提升了用户体验。这次开发不仅让我掌握了API的使用,也深刻体会到鸿蒙系统对用户隐私和数据安全的重视。 总结这次开发,我不仅学到了技术知识,还明白了开发者保护用户数据安全的责任。未来将继续探索更多功能,欢迎关注和收藏!
1118 70
自学HarmonyOS Next记录:实现相册访问功能
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
373 1
|
存储 安全 Java
ConcurrentHashMap的存储结构是怎样的
在Java并发编程中,ConcurrentHashMap是一个非常重要的数据结构,它提供了一种线程安全的哈希表实现。本文将深入探讨ConcurrentHashMap的底层存储结构,揭示其如何通过数组、链表和红黑树的结合来优化性能。
|
缓存 NoSQL Java
Spring Boot中的分布式缓存方案
Spring Boot中的分布式缓存方案
|
Android开发 容器 API
Android 扫码枪监听封装
一、参考 1、常用keycode 一、简述 1、设备:扫码枪其实相当于一个物理输入设备,如果软键盘打开的话能明显感觉到其内容在输入 2、问题: 2.1、不能扫出中文来(可能和扫码枪设备,配置有关系) 2.
2707 0
|
存储 算法 数据可视化
MySQL数据库 -- 索引结构 (B+ tree 与 Hash)
索引(index)是帮助MySQL高效获取数据的数据结构 , 在Mysql中有两个最常用的索引 -- B+tree索引 和 Hash索引 B-Tree(B树)是一种多叉路平衡查找树,相对于二叉树,B树每个节点可以有多个分支 哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中
758 0