await() 进入等待的状态
countDown() 计数器减一
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(8);
new Thread(()->{
try {
countDownLatch.await(); // 当前线程进入等待状态,需等下面8个线程执行完毕后才执行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("800米比赛结束,准备清空跑道并继续跨栏比赛");
}).start();
for (int i = 0; i < 8; i++) {
int finalI = i;
new Thread(()->{
try {
Thread.sleep(finalI * 1000L);
System.out.println(Thread.currentThread().getName()+"到达终点");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown(); // 当某个线程执行完毕后,计数器减1
}
}).start();
}
}
}
# 控制台执行结果:
Thread-1到达终点
Thread-2到达终点
Thread-3到达终点
Thread-4到达终点
Thread-5到达终点
Thread-6到达终点
Thread-7到达终点
Thread-8到达终点
800米比赛结束,准备清空跑道并继续跨栏比赛
# ctrl 查看await方法
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
# sync继承了aqs
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L;
Sync(int count) {
setState(count);
}
int getCount() {
return getState();
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
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;
}
}
}
# 当我们new CountDownLatch对象时,实际上是new sync
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
# 查看sync
Sync(int count) {
setState(count); // 赋值 state,即是count
}
# 返回await方法
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
# 继续查看acquireSharedInterruptibly方法
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted()) // 判断线程是否是中断状态
throw new InterruptedException();
if (tryAcquireShared(arg) < 0) // 否则执行tryAcquireShared方法
doAcquireSharedInterruptibly(arg);
}
# 查看实现类
protected int tryAcquireShared(int arg) {
throw new UnsupportedOperationException();
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1; // 判断状态是否为0,为0则返回1,否则返回-1
}
# 再次返回acquireSharedInterruptibly方法
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0) // 当返回值小于0时,执行doAcquireSharedInterruptibly方法
doAcquireSharedInterruptibly(arg);
}
# 查看doAcquireSharedInterruptibly方法
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED); // 添加1个节点
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) { // 判断node.predecessor是否等于head
int r = tryAcquireShared(arg); // 判断状态是否等于0
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) && // 否则挂起
parkAndCheckInterrupt())
throw new InterruptedException();
}
} catch (Throwable t) {
cancelAcquire(node);
throw t;
}
}
public void countDown() {
sync.releaseShared(1);
}
# 查看releaseShared方法
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
# 查看实现类
protected boolean tryReleaseShared(int arg) {
throw new UnsupportedOperationException();
}
protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
for (;;) { // 执行死循环
int c = getState(); // 获取状态
if (c == 0)
return false; // 等于0 则返回false
int nextc = c - 1; // 否则继续执行操作
if (compareAndSetState(c, nextc))
return nextc == 0; // 最后返回0
}
}
# 返回releaseShared方法
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared(); // 当8个线程的计数器减少为0时,执行doReleaseShared方法
return true;
}
return false;
}
# 查看doReleaseShared方法
private void doReleaseShared() {
/*
* Ensure that a release propagates, even if there are other
* in-progress acquires/releases. This proceeds in the usual
* way of trying to unparkSuccessor of head if it needs
* signal. But if it does not, status is set to PROPAGATE to
* ensure that upon release, propagation continues.
* Additionally, we must loop in case a new node is added
* while we are doing this. Also, unlike other uses of
* unparkSuccessor, we need to know if CAS to reset status
* fails, if so rechecking.
*/
for (;;) {
Node h = head;
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {
if (!h.compareAndSetWaitStatus(Node.SIGNAL, 0))
continue; // loop to recheck cases
unparkSuccessor(h);
}
else if (ws == 0 &&
!h.compareAndSetWaitStatus(0, Node.PROPAGATE))
continue; // loop on failed CAS
}
if (h == head) // loop if head changed
break;
}
}