JUC并发编程-6.CountDownLatch源码解析

1.CountDownLatch相关API使用

package com.ctgu.juc_project.source;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchTest {

    public static int threadCount = 3;
    public static int waitCount = 2;

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        ExecutorService runPool = Executors.newFixedThreadPool(threadCount);
        ExecutorService waitPool = Executors.newFixedThreadPool(waitCount);
        for (int i = 0; i < threadCount; i++) {
            runPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ": RUNNING");
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + ": WAITING");
        for (int j = 0; j < waitCount; j++) {
            waitPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ": WAITING");
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        runPool.shutdown();
        waitPool.shutdown();
    }

}

运行结果

pool-1-thread-2: RUNNING
pool-1-thread-3: RUNNING
pool-1-thread-1: RUNNING
main: WAITING
pool-2-thread-1: WAITING
pool-2-thread-2: WAITING

2.CountDownLatch相关API解读

  • new CountDownLatch(count)
new Sync(count)
setState(count)
private volatile int state

初始化设置共享资源volatile state,用于CAS操作

  • countDown()
tryReleaseShared(int releases)    CAS  state - 1 
当state - 1 == 0 时,执行doReleaseShared()
把当前结点设置为SIGNAL或者PROPAGATE,如果当前结点不是头结点也不是尾结点,先判断当前结点的状态位是否为SIGNAL,
如果是就设置为0,因为共享模式下更多使用PROPAGATE来传播,SIGNAL会被经过两步改为PROPAGATE
  • await()
doAcquireSharedInterruptibly()
在双向链表中生成共享模式的节点,第一次生成会先生成头结点然后指向Node(Shared),不然就加到上个节点的尾部
死循环堵塞,直到CAS将state减到0时,移除头结点,并将当前节点设置为头结点,清空GC

你可能感兴趣的:(JUC并发编程-6.CountDownLatch源码解析)