java并发编程 CountDownLatch详解

文章目录

  • 1 CountDownLatch是什么
  • 2 核心属性详解
  • 3 核心方法详解
    • 3.1 countDown()
    • 3.2 await()
  • 4 总结


java 并发编程系列文章目录

1 CountDownLatch是什么

java这个类上已经写了:一种同步辅助工具,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
其示例在类的注释上已经有很完整的。


2 核心属性详解

基于AQS实现了共享锁的方法。所以CountDownLatch可以看成多个线程同时获取指定的资源count,按照类的设计含义,等待所有线程都操作完成,同时唤醒向下执行。那么就是当AQS中的state减为0时,标志着所有线程完成。

	private final Sync sync;
	private static final class Sync extends AbstractQueuedSynchronizer {
       //...下面有详细解释
    }
    private final Sync sync;

3 核心方法详解

首先如果对AQS不熟悉,请先看AQS的相关知识java 并发编程系列文章目录

3.1 countDown()

	//让state - 1
	public void countDown() {
        sync.releaseShared(1);
    }
    protected boolean tryReleaseShared(int releases) {
        // Decrement count; signal when transition to zero
        for (;;) {
            int c = getState();
            // c == 0代表已经有线程cas设置成0了 所以就不需要去unpark线程了
            if (c == 0)
                return false;
            int nextc = c-1;
            if (compareAndSetState(c, nextc))
            	//此时state变成0 那么去唤醒线程,那些线程因为await()方法阻塞着的
                return nextc == 0;
        }
    }

3.2 await()

await方法是用来阻塞当前线程的,如果当前state 不是等于0的就会阻塞,

	//此时如果acquireShared state不是0 tryAcquireShared会返回-1 所以会添加shard的node到阻塞队列
	public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    //如果此时state != 0 那么会进行获取资源的操作 最后一个资源线程countDown时 此时自身线程是不会阻塞的,且countDown时执行
    //AQS的ReleaseShared方法,会去把阻塞队列里的shard的node全部unpark。doReleaseShared会从Head一个一个park
	//此时getState不是一个线程安全的方法,那么也不会造成影响,因为最后一个线程会countDown 唤醒所有线程之后同步调用await
    protected int tryAcquireShared(int acquires) {
    	return (getState() == 0) ? 1 : -1;
    }

4 总结

CountDownLatch 利用了AQS的共享锁队列实现了线程同步等待操作全部完成后执行下步操作。 到达指定点的线程countDown让共享资源state -1,await方法会阻塞住当前线程,只有当countDown把state变成0时会ReleaseShared唤醒队列中的线程。

你可能感兴趣的:(java并发编程,java,开发语言)