首先,我就不介绍CountDownLatch了,如果不知道的同学,可以参考一下:https://www.cnblogs.com/bqcoder/p/6089101.html
//这就是平时的使用方式了
/**
* (1)看一下构造方法
* (2)看一下await()方法
* (3)看一下countDown()方法
*/
CountDownLatch cdl=new CountDownLatch(1);
cdl.countDown();
cdl.await();
1.构造方法
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
Sync(int count) {
//将state设置为count
setState(count);
}
2.await()方法
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
//进入AQS的该方法中
public final void acquireSharedInterruptibly(int arg) throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
//返回-1时进入,即state不为0
//放入队列当中等待
doAcquireSharedInterruptibly(arg);
}
protected int tryAcquireShared(int acquires) {
//state == 0 则返回1,否则返回-1
return (getState() == 0) ? 1 : -1;
}
3.await()方法
public void countDown() {
sync.releaseShared(1);
}
public final boolean releaseShared(int arg) {
/**
* 由下面可以看出:只有state为0的时候才会进行下面操作
* 那么可以猜出来,是唤醒操作
*/
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
protected boolean tryReleaseShared(int releases) {
for (;;) {
int c = getState();
//等于0返回false
if (c == 0)
return false;
//state - 1
int nextc = c-1;
//判断state == 0 与否
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
//看一下唤醒操作,就是唤醒head
private void doReleaseShared() {
for (;;) {
Node h = head;
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue;
// loop to recheck cases
unparkSuccessor(h);
}
else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue;
// loop on failed CAS
}
if (h == head)
// loop if head changed
break;
}
}
4.await(long time,TimeUnit unit)—超时等待
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
这个好像比较简单,就那么两三个常用的api。就这样看完了。