zoukankan      html  css  js  c++  java
  • CountDownLatch源码剖析

      CountDownLatch 计数器设置默认的 count ,然后调用 await() 的线程会一直被挂起,直到 count 个线程都执行 countDown() 之后,被挂起的线程才会唤醒,接着走下面的逻辑。

        public static void main(String[] args) throws Exception{
            CountDownLatch latch = new CountDownLatch(2);
    
            new Thread(()->{
                try {
                    Thread.sleep(2000);
                    System.out.println("线程1准备执行 countDown 操作");
                    latch.countDown();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }).start();
    
            new Thread(()->{
                try {
                    Thread.sleep(2000);
                    System.out.println("线程2准备执行 countDown 操作");
                    latch.countDown();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }).start();
    
            System.out.println("main() 线程准备执行 await");
            latch.await();
            System.out.println("success");
        }

    CountDownLatch

      我们在创建 CountDownLatch 的时候,其实他就是一个 sycn 、继承了 aqs,可以猜到它的实现应该也是aps 那一套。首先就是将 count 赋值给了 state 标记锁状态。

    await

      主线程在 await() 的时候就等在了那里,直到所有线程执行完 countDown() , 主线程就继续往下执行。猜想他应该是进入了 aqs 的同步队列,直到其他线程将他唤醒。那我们就看看它的具体实现。

    1. tryAcquireShared() 获取 state ,我们初始化的时候设置的是2,那么此时肯定 !=0 。
    2. doAcquireSharedInterruptibly() 首先在 addWaiter() 里面for循环中循环两次将 当前线程加入等待队列中。
    3. 然后获取到上一个节点 p, 它肯定是一个空的头节点。
    4. 然后 tryAcquireShared() 再次判断一下锁占用状态。
    5. setHeadAndPropagate() 将当前节点设置为头节点(因为可能不止一个地方吊桶 await() ,所以通过指针的变化一个个遍历出来)
    6. 此时 r 肯定是>0 的,然后就 p.next=null 将自己从等待队中摘除出来
    7. 最后在 parkAndCheckInterrupt() 里面调用 LockSupport.park() 将自己挂起,等待别人的唤醒。

    countDown

    1. tryReleaseShared() 先获取 state ,如果 !=0 说明有人持有锁,那就 cas 操作 -1 返回true。
    2. doReleaseShared() 首先获取到头节点 h ,肯定不会为空的。
    3. 然后如果状态是 Node.SIGNAL 那就 cas 改成 0 。
    4. 最后在 unparkSuccessor() 里面获取头节点的下一个节点,也就是我们放在 同步队列 里面的main线程节点,通过 LockSupport.unpark() 唤醒它。

     

  • 相关阅读:
    asp.net保存网上图片到服务器
    一个强大的jquery分页插件
    JS全屏漂浮广告、移入光标停止移动
    使用C#类向数据库添加数据的例子源码
    pip安装报错Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-e_k8hq6a/pynacl/
    mycat启动报Unable to start JVM: No such file or directory (2)【转】
    pt-table-checksum校验与pt-table-sync修复数据【转】
    linux网卡参数NM_CONTROLLED【转】
    pt-table-checksum解读【转】
    pt-table-checksum报错Skipping chunk【转】
  • 原文地址:https://www.cnblogs.com/wlwl/p/15046807.html
Copyright © 2011-2022 走看看