CountdownLatch的实现原理如下
设置构造函数的
【1】构造函数
public Countdownlatch(int count){
if(count<0){
throw new IllegalArgumentException("count<0");
}
this.sync = new Sync(count);
}
【2】await 函数
public void await() throws InterruptedException{
sync.acquireSharedInterruptibly(1);
}
public final void acquireSharedInterruptible(int arg)throw InterruptedException{
if(Thread.interrupted()){
throw new InterruptedException();
}
if(tryAcquired(arg)<0){//尝试获取共享锁
doAcquireSharedInterruptibly(arg);//实现线程的入列与阻塞 获取共享锁失败
}
}
protected int tryAcquiredShared(int acquires){
return (getState()==0)?1:-1;
}
private void doAcquireSharedInterruptibly(int arg)throws InterruptedException{
final Node node = addWariter(Node.Shared);//添加至等待队列
boolean failed = true;
try{
for(;;){
final Node p = node.predecessor();
if(p==head){//前驱节点为头节点
int r = tryAcquireShared(arg);
if(r>0){//获取成功
//设置头节点并进行反战
setHeadAndPropagate(node,r);
//设置节点next 域
p.next = null;
failed = false;
return;
}
}
}
}
}
【3】countdown()方法
此函数将递减锁存器的计数,如果计数达到0,则释放所有等待的线程。
public void countDown(){
sync.releaseShared(1);//释放共享锁
}
releaseShared方法调用如下
//以共享模式释放对象,并且函数种会调用到CountdownLatch的tryReleaseeShared函数
//并且可能会调用AQS的doreleaseShared函数,其中tryReleaseShared函数
public final boolean releaseShared(int arg){
if(tryReleaseShared(arg)){//返回state减1以后,state==0的结果。如果是0,执行下面的代码
doReleaseShared();//实现会唤醒第一个节点,第一个节点会唤醒第二个节点。
return true;
}
return false;
}
//tryReleaseShared()的代码如下所示
protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;//返回当前state与0相等的结果
}
}