Phaser是java7版本添加的一个同步工具,相比CyclicBarrier、CountDownLatch、Semaphore等同步工具,Phaser使用更灵活而且可复用(CyclicBarrier也可复用),Phaser包含几个动作:

register:给Phaser增加parties,并且可以通过deRegister减少总parties(CyclicBarrier、CountDownLatch、Semaphore等工具不具备这种灵活性)。

arrive:parties已到达。

awaitAdvance:在所有parties都到达之前当前线程处于挂起等待状态,当所有parties都已到达之后线程被唤醒并且Phaser年龄增加,未到达parties数还原,Phaser复用。

Phaser通过status字段来实现同步逻辑,status是一个64位的long变量,它有包含了四个维度的语义:

1、第0-15位,当前未到达的parties,调用arriveXXX时,该值-1,调用register时+1;

2、第16-31位,当前总parties,调用register时+1,deRegister时-1;

3、第32-62位,phase,即Phaser的年龄,当未到达的parties减到0(即所有parties已到达)时,phase自动加1,并且把16-31位的parties数复制到0-15位,从而该Phaser可以继续复用;

当Phaser的parties数比较大的高并发场景下,Phaser的status变量的竞争会非常激烈,register、arrive等操作发起的CAS操作预测将会大概率失败导致大量CAS操作被重复调用,增加CPU开销。可以通过构造Phaser分层树的方式来分离竞争,子Phaser第一次register时,把该子Phaser注册到父Phaser,当子Phaser所有parties都已经arrive时,把它从父Phaser中反注册。

当根Phaser的所有子Phaser的parties都已经arrive时,整个Phaser树升级phase递增,通过这种方式,所有的arrive、register操作在子Phaser进行就可以,根Phaser只需负责Phaser的升级,这样可以把部分对status的访问修改分离到子Phaser中,通过分散竞争点提高Phaser的吞吐量。

下面示例代码就把9个parties分散到了两个子Phaser中:

注册parties时,主要做的事情就是修改status变量的parties部分和unarrive部分,同时也可以看到,在第一注册时,调用了代码parent.doRegister(1),注册一次party到父Phaser。

线程触发arrive操作时,如果当前Phaser的所有parties都已经arrive,那么调用一次parent.doArrive(1),如果所有parties都已经arrive并且当前Phaser时根Phaser,说明该Phaser可以升级,phase值加1,唤醒由于调用了awaitXXX被阻塞的线程。在升级时有个onAdvance回调可以让调用者终止Phaser。

触发Phaser的awaitAdvance时,Phaser的await操作不会直接挂起线程,会先对根Phaser的status自旋检查,检查phase是否发生了变化,自旋了若干次(这个数值跟当前CPU的核心数有关)之后如果phase还未发生变化则挂起线程,这样做的目的是挂起线程会造成上下文切换,如果Phaser在很短的时间内就升级了,那么这样就减少了上下文切换次数提高CPU吞吐量,但是自旋检查也会造成CPU消耗,所以也不能一直自旋。在上面的arrive方法中可以看到,当所有parties都arrive之后修改phase值加1,所以internalAwaitAdvance方法中的while条件将不成立,跳出循环唤醒所有等待的线程。下面是唤醒线程的方法:

这个方法相对简单,就是有一点需要注意的是:有两个线程等待队列头节点分别是evenQ和oddQ,这是因为在并发场景下,老Phaser所有parties都已经arrive之后等待队列的线程正在被唤醒,但是此时又有线程在对升级后的Phaser调用了await,如果只有一个队列的话那么此时队列头结点出现激烈的竞争,所以这里面把相邻的年龄的Phaser等待线程放在两个队列中可以达到分离竞争的目的。

phaser java_java并发编程:Phaser同步工具原理相关推荐

  1. Java高并发编程:同步工具类

    内容摘要 这里主要介绍了java5中线程锁技术以外的其他同步工具,首先介绍Semaphore:一个计数信号量.用于控制同时访问资源的线程个数,CyclicBarrier同步辅助类:从字面意思看是路障, ...

  2. Java 并发编程之同步工具类闭锁 CountDownLatch

    Java 同步工具类CountDownLatch相当于一个计数器,假设一个方法,等待一个计数器从初始值5变为0,每使用一次countdown()方法,计数器的值减少1,当计数器的值为0时,触发某件事. ...

  3. Java 并发编程之同步工具类 Exchanger

    Exchanger 交换器,用于两个线程之间交换数据. 线程1调用exchange()方法,然后进行线程阻塞,等待线程2调用exchange()方法交换数据,线程2调用exchange()方法后,两个 ...

  4. Java 并发编程之同步工具类栅栏 CyclicBarrier

    CyclicBarrier 用来阻塞一组线程,等待线程完成后才开始某件事情. 例如,开启5个线程,每个线程使用await方法开始阻塞,等待5个线程都完成,才开始执行await方法后面的代码. publ ...

  5. Java 并发编程之同步工具类信号量 Semaphore

    Semaphore 可以理解为一个阈值,正在进行的操作数量不能超过此阈值,可以用来限制资源的访问,或者控制某个队列中对象的个数,也就是控制同时执行的线程的数量. 主要有acquire,release两 ...

  6. python 线程同步_Python并发编程-线程同步(线程安全)

    Python并发编程-线程同步(线程安全) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 线程同步,线程间协调,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直 ...

  7. phaser java_Java 7的并发编程-Phaser

    Java 7的并发包中推出了Phaser,其功能跟CyclicBarrier和CountDownLatch有些重叠,但是提供了更灵活的用法,例如支持动态调整注册任务的数量等.本文在Phaser自带的示 ...

  8. java虚拟机线程调优与底层原理分析_Java并发编程——多线程的底层原理

    " Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和 CPU的 ...

  9. Java并发编程—线程同步类

    原文作者:洲洋1984 原文地址:Java 并发包中的高级同步工具 Java 中的并发包指的是 java.util.concurrent(简称 JUC)包和其子包下的类和接口,它为 Java 的并发提 ...

  10. Java并发编程 Synchronized及其实现原理

    Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法.Synchronized的作用主要有三个:(1)确保线程互斥的访问同步代码(2)保证共享变量的修改能够及时可见 ...

最新文章

  1. arm 饱和指令_ARM平台下NEON使用方法详解
  2. win10下如何查看电脑名称?查看计算机名(win+r -- cmd -- hostname)
  3. u852日期限制解决补丁_用友U8hotfix和补丁包替换原则及注意事项
  4. 【题解报告】Leecode367. 有效的完全平方数——Leecode每日一题系列
  5. 前端实操案例丨如何实现JS向Vue传值
  6. 如何在脱敏数据中使用BERT等预训练模型
  7. c语言模糊pid算法实例,模糊PID的c语言算法.docx
  8. 学习记录:UI自动化断言那些内容
  9. PEER地震库地震波获取方法
  10. 互联网日报 | 360企业安全更名“政企安全”;B站获欢喜传媒独家外部播放权;银联发布首款数字银行卡...
  11. Win11蓝牙耳机已连接电脑仍外放怎么解决
  12. 用两种while循环求2的n次方,n是传入的值。
  13. 专题-参数方程与极坐标
  14. 笔记本中的insert,idea中Alt + insert快捷键在笔记本中怎么输入
  15. Android Studio 单击按钮放大字体
  16. 基于SSM的校园运动会管理系统
  17. 远程连接服务器突然失败
  18. 使用遗传算法和模拟退火改进的K均值聚类
  19. C# 加密-密钥容器
  20. 腾讯通 linux,Ubuntu 手记之RTX (腾讯通)

热门文章

  1. 《大数据之路:阿里巴巴大数据实践》第一篇 数据技术篇-读书笔记
  2. .net获取mysql数据_asp.net用DataSet从数据库中获取数据
  3. python统计套利_统计套利——反转定律
  4. 后分布式时代: 多数派读写的「少数派」实现
  5. SQL Sever创库
  6. 竞赛资讯|阿里小蜜机器人跨语言短文本匹配算法竞赛
  7. MediaCodec编码后视频时长不正确的问题
  8. word撰写格式系列2
  9. HTML实例—以一个简单网页为例
  10. 利用ode45求解含控制量并且控制量为离散点的动力学方程