Java多线程---Phaser
Phaser是Java7新引入的并发API,我们可以将Phaser的概念看成是一个个的阶段, 每个阶段都需要执行的线程任务,任务执行完毕后就进入下一阶段。这里和CyclicBarrier 和CountDownLatch的概念类似, 实际上也确实可以用Phaser代替CyclicBarrier和CountDownLatch。
Phaser也是通过计数器来控制, 在Phaser中叫parties, 我们在指定了parties之后, Phaser可以根据需要动态增加或减少parties的值。
Phaser常用API介绍:
构造方法: public Phaser() {this(null, 0);}public Phaser(int parties) {this(null, parties);}public Phaser(Phaser parent) {this(parent, 0);}public Phaser(Phaser parent, int parties) {if (parties >>> PARTIES_SHIFT != 0)throw new IllegalArgumentException("Illegal number of parties");int phase = 0;this.parent = parent;if (parent != null) {final Phaser root = parent.root;this.root = root;this.evenQ = root.evenQ;this.oddQ = root.oddQ;if (parties != 0)phase = parent.doRegister(1);}else {this.root = this;this.evenQ = new AtomicReference<QNode>();this.oddQ = new AtomicReference<QNode>();}this.state = (parties == 0) ? (long)EMPTY :((long)phase << PHASE_SHIFT) |((long)parties << PARTIES_SHIFT) |((long)parties);}
从上面可以看出, Pahser是存在上下级关系的树状结构, 如果不指定parent和parties默认为null和0。后面我们再对parent结构进行说明。先看看它常用API和对应的功能。
public int register() //向此移相器添加一个新的未到达方。public int bulkRegister(int parties) // 将给定数量的新未到达方添加到此移相器。public int arriveAndDeregister() // 到达此移相器并从其注销,而无需等待其他人到达public int arrive() // 到达此移相器,无需等待其他人到达public int arriveAndAwaitAdvance() // 到达这个移相器并等待其他人public int awaitAdvance(int phase) // 等待此移相器的相位从给定的相位值前进,如果当前相位不等于给定的相位值或此移相器终止,则立即返回。public int awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit) // 等待此移相器的相位从给定的相位值或给定的超时时间过去,InterruptedException如果在等待时中断则抛出,或者如果当前相位不等于给定的相位值或此移相器终止,则立即返回public final int getPhase() // 返回当前阶段号public int getRegisteredParties() // 返回在此移相器上注册的参与方数量public int getArrivedParties() // 返回已到达此移相器当前阶段的已注册方的数量public int getUnarrivedParties() // 返回尚未到达此移相器当前阶段的已注册方的数量。
这里列出了Phaser的部分API和功能说明。 下面我们就看一下这些API的具体用法。
1、Phaser代替CountDownLatch: arrive、awaitAdvance
public static void main(String[] args) {Phaser phaser = new Phaser(5);for (int i = 0; i < 5; i++) {new Thread(() -> {synchronized (phaser) {System.out.println(Thread.currentThread().getName() + "running");phaser.arrive();}}, "thread" + i).start();}System.out.println(Thread.currentThread().getName() + " wait");phaser.awaitAdvance(phaser.getPhase());System.out.println(Thread.currentThread().getName() + "线程执行完毕");}
这里要注意, arrive方法不是线程安全的,如果不加锁,方法很难结束。
输出结果:
这样无论执行多少次, “ main线程执行完毕 ” 这句话都是最后才输出。 我们可以尝试一下,将phaser.arrive() 的调用时机提前,看看方法的执行结果。
2、用phaser代替CyclicBarrier: arriveAndAwaitAdvance
Phaser phaser = new Phaser(5);for(int i=0; i<5; i++){new Thread(()->{System.out.println("=========" + Thread.currentThread().getName());phaser.arriveAndAwaitAdvance();System.out.println("***" + Thread.currentThread().getName());phaser.arriveAndAwaitAdvance();System.out.println("##########" + Thread.currentThread().getName());}).start();}
输出结果:
3.phaser其他API演示:
public static void main(String[] args) {Phaser phaser = new Phaser(5);for(int i=0; i<5; i++){new Thread(()->{synchronized (phaser){phaser.arrive();System.out.println("phaser.getPhase() = "+phaser.getPhase());System.out.println("phaser.getArrivedParties() = "+phaser.getArrivedParties());System.out.println("phaser.getUnarrivedParties() = "+phaser.getUnarrivedParties());}if(Thread.currentThread().getName().equals("thread4")){try {Thread.sleep(1000);System.out.println("=======phaser.getPhase() = "+phaser.getPhase());phaser.arriveAndDeregister();System.out.println("========phaser.arriveAndDeregister() = "+phaser.getPhase());} catch (InterruptedException e) {e.printStackTrace();}}}, "thread"+i).start();}phaser.bulkRegister(3);}
执行结果:
Java多线程---Phaser相关推荐
- java多线程下LongAdder、CountDownLatch、CyclicBarrier、Phaser 的用法
前言 一文读懂java多线程下常用常考的阻塞方法LongAdder.CountDownLatch.CyclicBarrier.Phaser 包含演示代码 高并发模拟,性能比较实例代码 前言 LongA ...
- Java多线程发展简史
摘自: http://www.raychase.net/698 这篇文章,大部分内容,是周五我做的一个关于如何进行Java多线程编程的Knowledge Sharing的一个整理,我希望能对Java从 ...
- [转] Java多线程发展简史
这篇文章,大部分内容,是周五我做的一个关于如何进行Java多线程编程的Knowledge Sharing的一个整理,我希望能对Java从第一个版本开始,在多线程编程方面的大事件和发展脉络有一个描述,并 ...
- Java 多线程 并发编程
转载自 Java 多线程 并发编程 一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进 ...
- java 多线程 一个博客
http://blog.csdn.net/a352193394/article/category/2563875 Java多线程之~~~线程安全容器的非阻塞容器 在并发编程中,会经常遇到使用容器.但是 ...
- 关于java多线程你需要知道的万字真言
关于java多线程你需要知道的万字真言 程序?进程?线程 线程 个数设置 状态 create runnable runnig blocking / waiting terminate interrup ...
- Java 多线程发展简史
历史热门文章: 可以和面试官聊半个小时的volatile原理 Java中七个潜在的内存泄露风险,你知道几个? JDK 16新特性一览 啥?用了并行流还更慢了 InnoDB自增原理都搞不清楚,还怎么CR ...
- Java多线程和并发问题集
并发是指什么 并发是程序同时执行多个计算的能力. 这可以通过将计算分布在机器的可用CPU内核上(多核CPU支持)或甚至通过同一网络内的不同机器来实现(后台分布式). 进程和线程有什么区别 进程是操作系 ...
- Java多线程系列之J.U.C并发包概述
J.U.C包简介 J.U.C并发包,即java.util.concurrent包,是JDK的核心工具包,是JDK1.5之后,由 Doug Lea实现并引入. 整个java.util.concurren ...
- Java多线程进阶(一)—— J.U.C并发包概述
本文首发于一世流云专栏: https://segmentfault.com/blog... J.U.C包简介 J.U.C并发包,即java.util.concurrent包,是JDK的核心工具包,是J ...
最新文章
- UVa11402 Ahoy, Pirates!
- 太神奇了!使用C#实现自动核验健康码:(2)OCR识别
- 12个有趣的C语言面试题
- HTML跳转为啥会404,为什么网页会出现404 not found?
- git学习(二):git config命令
- 计算机系统建模_包图
- java dh算法_java 非对称加密算法DH实现详解
- MATLAB多项式计算
- 全国多地打造城市三维实景模型 给城市管理带来新利器
- 避免让WPF资源字典变得杂乱臃肿
- 【Android多屏适配】动态改变Listview item高度
- 《Graph neural networks A review of methods and applications》翻译
- 期货如何展期(期货合约展期)
- 安卓仿苹果音量调节_Android实现音量调节的方法
- 51使用LCD1602液晶显示(复习总结)
- 微信小程序国际化语言包实现方式(di18n-translate)
- openssl漏洞检查修复
- SAAS平台构建-后端方案
- 【Latex】算法排版规律(中文排版)
- 爬虫踩坑系列——etree.HTML解析异常