Phaser类是Jdk
1.7新增的类,用来解决CyclicBarrier不能动态增加parties计数、调用一次await()仅仅占用一个parties计数等问题。
Phaser翻译为移相器。Phaser对计数的操作是加法操作。
arriveAndAwaitAdvance()方法与CyclicBarrier的await()用法相同,阻塞并等待parties。如果没有足够的parties,会一直等待下去。
arriveAndDeregister()
使当前线程退出比赛,并且使parties值减1.从而其他线程可以少等一个parties而不会被该线程的退出而阻塞。
getPhase()获取已经到达了第几个屏障。也就是比赛已经进行到第几轮。
boolean
onAdvance(int phase,
int
registeredParties)在凑够了parties,通过新的屏障时被调用。如果想要使用,首先覆盖onAdvance方法,并且使用带onAdance方法的Phaser构造器构造phaser。返回false表示Phaser继续工作。返回true则是不等待了,Phaser呈无效/销毁状态。此时强行使用getPhase()或获得值-2147483647。代表无效。
getRegisteredParties()获得注册的parties数量,默认返回构造时输入的parties值。
register() 动态增加一个parties。
bulkRegister(int
parties) 批量增加parties数量。
getArrivedParties()
获得已经被使用的parties个数
getUnarrivedParties()获得未使用的parties个数
arrive()
parties值加一,并且不在屏障处等待,继续运行。arrive()的功能是使getArrivedParties()计数加1,如果控制台多次出现getArrivedParties=0,可能是Phaser类在经过屏障点计数后被重置。
如果一个线程使用了arrive()方法,而另外两个线程使用arriveAndAwaitAdvance()方法。phaser的parties是3,则第一个线程正常运行,另外两个一直等待。
awaitAdvance(int
phase)如果传入的phase值与当前getPhase()方法返回值一样,则在屏障处等待。否则继续运行。类似于旁观者。该方法并不参与parties计数的操作,仅仅具有判断的功能。等待在awaitAdvance()方法的线程是不可中断的。
awaitAdvanceInterruptibly(int
phase)等待在该方法的线程是可中断的。当线程执行的栏数不符合指定的参数值时,则继续执行下面的代码。
awaitAdvanceInterruptibly(int phase,
long timeout, TimeUnit unit)
是可以中断的。如果等待timeout后,仍然是一致的,则会超时异常。等待时间内,栏数变化,会继续向下运行。
forceTermination()将屏障取消,所有等在屏障前的parties会继续运行。这与CyclicBarrier类的reset()不同,后者执行时会抛出异常。
isTerminated()屏障是否被消除。
register()和arriveAndDeregister()组合使用可以控制任务执行的时机。
代码示例:https://github.com/whitefancy/JavaTechnologystack/tree/master/javaconcurrent/Phaser
参考文档
《Java并发编程
核心方法与框架》(高洪岩)