• 并发编程(九)抽象队列同步器AQS解析


    一、背景介绍

      学习AQS前先了解一位巨佬,也就是java.util.concurrent包的作者Doug Lea

      Java并发编程核心在于java.concurrent.util包,而JUC当中的大多数同步器实现都是围绕着一些共同的基础行为去实现的,比如:

    • 等待队列
    • 条件队列
    • 独占获取
    • 共享获取等

      定义:而这些行为的抽象就是基于AbstractQueuedSynchronizer简称AQS,AQS定义了一套多线程访问共享资源的同步器框架,是一个依赖状态【state:表示资源的可用状态】的同步器。

      PS:AbstractQueuedSynchronizer位于java.util.concurrent.locks包下,是一个抽象类,像我们常用的ReentrantLockCountDownLatch内部会对这个AbstractQueuedSynchronizer这个类进行继承。

      PS:AQS底层有一个队列容器来存放被阻塞的线程(用队列的原因是因为要实现公平锁的概念【排队】)【AQS也是这个队列的缩写】

    二、AQS具备特性

    基本特性

    • 阻塞等待队列
    • 共享/独占
    • 公平/非公平
    • 可重入
    • 允许中断

    框架实现思路

    • 1、定义内部类Sync继承AQS
    • 2、将同步器所有调用都映射到Sync对应的方法

    state三种访问方式

    • getState()
    • setState()
    • compareAndSetState()

    AQS定义两种资源共享方式

    • Exclusive-独占:只有一个线程能执行,如ReentrantLock
    • Share-共享:多个线程可以同时执行,如Semaphore/CountDownLatch

    三、AQS的两种队列

    同步等待队列

      同步等待队列也称CLH队列【作者姓名字母缩写】,是一种基于双向链表数据结构的队列,是FIFO先入先出线程等待队列,由阻塞机制实现。

    条件等待队列

      队列结构与上图类似,就不重复赘述了。【condition条件队列在后面会去学习】

    四、Lock锁内部的一些关键方法

    isHeldExclusively()

      作用:判断该线程是否正在独占资源。

      PS:只有用到condition才需要去实现它。

    tryRelease(int state减少的量)【独占的锁有对应的实现方法,如ReentrantLock】

      作用:尝试释放资源,成功则返回true,失败则返回false。

     

    tryAcquire(int state增加的量)【独占的锁有对应的实现方法,如ReentrantLock】

      作用:尝试获取资源,成功则返回true,失败则返回false。

    tryAcquireShared(int)【共享的锁有对应的实现方法,如CountDownLatch】

      作用:尝试获取共享锁,实现方式和独占锁类似。

    • 负数表示失败
    • 正数表示成功,且有剩余资源

      PS:state 状态变量,state 的值代表着等待的线程数,比如初始化为 5,表示正在等待的线程数为 5,每次调用 countDown() 函数都会减1。

    tryReleaseShared(int)【共享的锁有对应的实现方法,如CountDownLatch】

      作用:尝试释放共享资源,如果释放后允许唤醒后续 等待结点返回true,否则返回false。

     

  • 相关阅读:
    Linux监控和安全运维 2.0 zabbix配置邮件告警
    Linux监控和安全运维 1.9 zabbix增加客户端监控
    linux系统构架
    给虚拟机添加eth1网络适配器(网卡)
    linux系统构架
    linux系统构架
    Linux系统构架
    VIM-Sed常用的一些记录。。。逐渐学习。。
    AIX用chsec命令修改快捷修改配置文件
    SYSLOG审记日志的配置。
  • 原文地址:https://www.cnblogs.com/riches/p/15013660.html
Copyright © 2020-2023  润新知