CountDownLatch

一、介绍

CountDownLatch是一个并发工具类,它的作用是可以完成线程的协作,通常的场景是 主线程等待 多个子线程执行完成后再处理,类似于Jion功能。

二、使用方法
   public static void main(String[] args) throws Exception {
        // 设置挡板数量
        final CountDownLatch latch = new CountDownLatch(10);
        for (int i = 0; i <= 9; i++) {
            final  int num = i;
            new Thread(()->{
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    log.info("this thread id is {} and i is {} ",Thread.currentThread().getName(),num);
                    latch.countDown();
                }

            }).start();
        }

        latch.await();
        log.info("fish and latch count is {}",latch.getCount());

    }
三、源码分析
  • 初始化CountDownLatch,其内部也是依拖于AQS框架实现的
  public CountDownLatch(int count) {
      if (count < 0) throw new IllegalArgumentException("count < 0");
      // 创建同步处理器  
      this.sync = new Sync(count);
    }

// 继承自AbstractQueuedSynchronizer
 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;
            }
        }
    }


  • 关键方法:获取资源tryAcquireShared如果当前count == 0 返回1,否则返回-1 (这个判断很关键,后面会讲到)
3.1 为什么await()方法能够等待
 public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

它调用的是同步器的共享锁获取,看一下具体的实现:

    public final void acquireSharedInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        //
        if (tryAcquireShared(arg) < 0)
            // 进入队列,自旋等待
            doAcquireSharedInterruptibly(arg);
    }

可以看到代码,如果tryAcquireShared小于0 ,那么该线程就进入自旋等待。也就符合上的逻辑,当count >0时 返回 -1.。那么就能够猜测到,当执行countDown方法时,就是使 stateCount 状态 -1.

3.2 CountDown()方法
	// 
    public void countDown() {
        sync.releaseShared(1);
    }

   protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                // 状态Count - 1;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }

3.3 小结

CountDownLathch的实现原理依托于AQS,设置的挡板数量Count,就是AQS的共享状态资源。主任务线程await()时,判断count是否 == 0, 否则会进入等待队列,自旋。

4 参考

《并发编程的艺术》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值