CyclicBarrier与CountDownLatch区别:
CycliBarrier可以重用,而CountDownLatch不可以。在设计上之所以可以重用,是因为CycliBarrier中是一群线程在等一个状态,这个状态有自身打破,而CountDownLatch是一群线程在等待一个状态。这个状态由另外的线程打破。
CountDownLatch类实现
public class CountDownLatch extends Latch{
public CountDownLatch(int limit){
super(limit):
}
@Override
pubic void await()throws InterruptedException{
synchronized(this){
while(limit > 0){
this.wait();
}
}
}
@Override
public void countDown(){
synchronized(this){
if(limit <= 0)
throw new IllegalStateException("all of task already arrived");
limit --;
this.notifyAl();
}
}
@Override
public int getUnarrived(){
return limit;
}
}
带超时的CountDownLatch
public void await(long time) throws InterruptedException,WaitTimeOutException{
if(tim <= 0)
throw lIIegalArgumentException();
//转换成纳秒
long remainingNanos = unit.toNanos(time);
final long endNanos = System.nanoTime() + remainigNanos;
synchronized(this){
while(limit > 0){
if(TimeUnit.NANOSECONDS.toMaills(remainingNanos) < =0)
throw new WaitTimeoutException();
//最长堵塞存留时间
this.wait(TimeUnit.NANOSECONDS.toMills(remainingNanos));
remainingNanos = endNanos - System.nanoTime();
}
}
}
CycliBarrier模式退出条件
判断线程局部Generation是否与全局的Generation相等
/**
* Main barrier code, covering the various policies.
*/
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException,
TimeoutException {
final ReentrantLock lock = this.lock;
lock.lock();
try {
final Generation g = generation;
if (g.broken)
throw new BrokenBarrierException();
if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
}
int index = --count;
if (index == 0) { // tripped
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}
// loop until tripped, broken, interrupted, or timed out
for (;;) {
try {
if (!timed)
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
// We're about to finish waiting even if we had not
// been interrupted, so this interrupt is deemed to
// "belong" to subsequent execution.
Thread.currentThread().interrupt();
}
}
if (g.broken)
throw new BrokenBarrierException();
if (g != generation)
return index;
if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
}