zoukankan      html  css  js  c++  java
  • 谈谈对AQS的一些理解

    AQS的概念

    AQS全称AbstractQueuedSynchronizer,是java并发包中的核心类,诸如ReentrantLock,CountDownLatch等工具内部都使用了AQS去维护锁的获取与释放:


    AQS内部结构

    首先我们可以找到这样一张图:

    它描述了其内部是如何维护线程的状态,以及锁的获取。类似于一个阻塞队列,当前持有锁的线程处于head(记住不是在阻塞队列中),新进来的无法获取到锁的线程则被包装成为一个Node节点依次放于队尾。
    我们可以看到其内部几个核心的属性:
    head:当前持有锁的线程
    tail:阻塞队列中未获取到锁的线程
    state:这是AQS里面最重要的一个变量,锁的获取与释放都与其密切相关。当它等于0时,表示没有线程持有锁,当大于0(锁可重入,每次获取锁,state加1)时表示有线程持有锁。
    再看看线程时如何进行包装,然后放于阻塞队列的:


    每一个线程都会被包装称为一个Node节点存储于阻塞队列中,SHARED和EXCLUSIVE分别指当前线程是期望获取共享锁,还是独占锁。
    waitSatus:当大于0时表示当前线程放弃了争取锁。
    prev:前一个节点
    next:后一个节点
    thread:所封装着的线程

    内部实现

    AQS通过以下方法去控制锁的获取和释放:
    acquire(int arg):用于获取独占锁
    很简单,首先尝试获取锁,如果获取失败,说明有线程持有锁,则将其加入当等待队列的末尾。
    release(int arg):用于释放独占锁
    如果当前线程不为空,且后面有等待的线程,则唤醒后序线程获取锁。
    acquireShared(int arg):
    不多说,即用于获取共享锁。
    tryReleaseShared(int arg):
    用于释放共享锁

    总结

    AQS内部通过一个CLH阻塞队列去维持线程的状态,并且使用LockSupport工具去实现线程的阻塞和和唤醒,同时里面大量运用了无锁的CAS算法去实现锁的获取和释放。今后再继续分享具体的并发包里面是如何通过AQS去实现更多丰富的并发工具。
    ————————————————
    版权声明:本文为CSDN博主「呛水鱼」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/jackFXX/article/details/81104871

  • 相关阅读:
    C#获取视频文件播放长度
    ViewState跨页传值
    radio点击事件
    js屏蔽鼠标右键
    js获取url参数
    js页面跳转
    android 界面刷新功能
    android RadioButton单选按钮效果
    android TextView实现跑马灯效果(字体滚动)
    android 圆角效果
  • 原文地址:https://www.cnblogs.com/eryun/p/12040087.html
Copyright © 2011-2022 走看看