Phaser详解
简介
一种可重用的同步栅栏,功能与CyclicBarrier和CountDownLatch类似.
内部使用CAS操作保证原子性.
运行机制
注册机制
Phaser中注册的同步者(parties)会随着时间的变化而变化.
Phaser可通过构造器初始化parties个数,也可以在运行期间随时加入(register)新的parties,以及在运行期间注销(deregister)parties.
注册和注销只会影响Phaser内部的计数器,任务不能查询自己是否已经注册.
CyclicBarrier和CountDownLatch需在初始化时设定同步者的个数,运行时无法修改.
同步机制
Phaser的每个周期(generation)都有一个phase值,从0开始计数.
当所有的已注册的parties到达(arrive)后,该phase会自增.
phase到达Integer.MAX_VALUE后继续从0开始.
phase表示当前parties所处的阶段.
用来控制线程等待唤醒的时机.
到达机制(arrive)
arrive()和arriveAndDeregister()不会阻塞线程,直接返回对应的phase值.
当前phase最后一个线程到达时,phase会自增.同时触发onAdvance方法,释放所有阻塞在phase的线程.
等待机制(wait)
awaitAdvance()需要指定一个phase,表示线程阻塞到当前phase到达指定的周期.
arriveAndAwaitAdvance():阻塞线程直到当前phase结束.
当前的线程被中断时,awaitAdvance()继续等待.
中断机制
当Phaser被终止时,所有的同步方法立即返回一个负的phase值.
向一个终止的Phaser注册不会生效.
onAdvance()返回true,表示所有的parties都已注销.
分层(Tiering)
通过分层降低竞争.
一个Phaser有大量的parties会导致严重的同步竞争.
可以将多个parties分组共享parent Phaser,提高吞吐量.
当Child Phaser的parties非0时,其会注册到Parent Phaser.
当Child Phaser的parties为0时,会从Parent Phaser注销.
监控机制
监控方法并非同步,只能反映当前瞬间的状态.
getRegisteredParties():获取已注册的parties个数.
getPhase()获取当前phase周期数.
方法解释
状态
Phaser内有两个状态:
phase:当前的阶段,初始值为0,当所有线程完成本轮任务,同时开启下一轮任务时,phase值加1.
party:当前Phaser对象管理的线程数.
方法
一个可以重载的方法:onAdvance(int phase, int registeredParties).
作用:
当每个阶段执行完毕后,此方法被自动调用.
此方法返回true表示Phaser被终止.(返回值用来终止所有线程)
arriveAndAwaitAdvance()
表示当前线程完成当前阶段的任务,等待其他线程完成当前阶段的任务.
若当前线程为本阶段中最后一个到达的,则直接返回下一个阶段的序号,并且其他线程也返回下一个阶段的序号.
arriveAndDeregister()
当前线程立即返回下一阶段的序号,并且从Phaser中移出当前线程,其他线程在调用arriveAndAwaitAdvance()时不需要等待当前线程.
arrive()
不等待,直接返回下一个阶段的序号.
awaitAdvance(int phase)
该方法等待某一阶段执行完毕.
若当前阶段不等于指定的阶段或该Phaser已被终止,则立即返回.
若参数为负,则直接返回指定的参数.
若Phaser已被终止,则返回当前阶段的序号.
否则返回下一个阶段的序号.
awaitAdvanceInterruptibly(int phase)
方法等待过程中被中断则抛出异常.
bulkRgister(int parties)
注册多个party.
若当前Phaser被终止,则方法无效,返回负数.
若onAdvance()正在执行,则等待其执行完毕.
若父Phaser指定的party大于0,而此Phaser的party为0,则该Phaser被注册到父Phaser中.
forceTermination()
强制该Phaser进入终止状态.
已注册的party不受影响.
子Phaser也进入终止状态.
参考: