开发者社区> 在下uptown> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

浅谈AQS原理

简介: 经典八股文之AQS原理
+关注继续查看

Java相关文章


AQS底层原理

  1. AQS核心思想
    1. AQS内部维护了一个核心变量state和两种队列:主队列(Main Queue)、条件队列(Condition Queue)
    2. 如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。
    3. 如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁实现的,即将暂时获取不到锁的线程加入到主队列中竞争锁
    4. 如果被请求的共享资源满足条件队列的阻塞条件则进入条件队列中阻塞。
  1. 内部结构
    1. 维护了一个volatie int state的共享变量和一个先进先出的队列queue
    2. AQS定义了两种资源共享方式
      1. 独占模式
        1. 只有一个线程能获取到共享变量
        2. 以ReentrantLock为例,当state变量初始值为0,表示未锁定状态。
        3. 线程A访问的时候,state+1,就代表该线程锁定了共享资源,其他线程将无法访问
        4. 而当线程A访问完共享资源以后,state-1,直到state等于0,就将释放对共享变量的锁定,其他线程将可以抢占式或者公平式争夺。
        5. 当然,ReentrantLock支持可重入,那什么是可重入呢?同一线程可以重复锁定共享资源,每锁定一次state+1,也就是锁定多次。说明:锁定多少次就要释放多少次
      1. 共享模式
        1. 共享,多个线程可以同时执行,如 CountDownLatch、CyclicBarrier、Semaphore、ReadWriteLock
        2. 以CountDownLatch为例,共享资源可以被N个线程访问,也就是初始化的时候,state就被指定为N(N与线程个数相等),线程countDown()一次,state会CAS减1,直到所有线程执行完(state=0),那些await()的线程将被唤醒去执行执行剩余动作。
  1. 加锁步骤

image



同步队列与条件队列

  1. image
  2. 同步队列存放着竞争同步资源的线程的引用(不是存放线程),而等待队列存放着待唤醒的线程的引用。
  3. 调用condition的await方法,将会使当前线程进入等待队列并释放锁(先加入等待队列再释放锁),同时线程状态转为等待状态
  4. 调用condition的signal方法时,将会把等待队列的首节点移到同步队列的尾部,然后唤醒该节点。
    争抢资源,争抢失败进入同步队列中
  5. 以BlockingQueue为例
    1. 一般会有两个等待队列,用lock.newCondition()
    2. 一个用于队列满时阻塞插入线程的等待队列
    3. 一个用户队列为空时阻塞获取线程的等待队列



AQS有哪些实现

  1. ReentrantLock
    1. 独享
  1. CountDownLatch
    1. 线程计数器
    2. CountDownLatch是通过一个计数器来实现的,计数器的初始化值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就相应得减1。当计数器到达0时,表示所有的线程都已完成任务,然后在闭锁上等待的线程就可以恢复执行任务。
    3. 利用AQS调度共享模式,多个线程可以同时执行,共享资源可以被N个线程访问,也就是初始化的时候,state就被指定为N(N与线程个数相等),线程countDown()一次,state会CAS减1,直到所有线程执行完(state=0),那些await()的线程将被唤醒去执行执行剩余动作。
  1. CyclicBarrier
    1. CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:
    2. CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行; 而
    3. CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;
    4. CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
AQS(abstractQueuedSynchronizer)锁实现原理详解
AQS(abstractQueuedSynchronizer)抽象队列同步器。其本身是一个抽象类,提供lock锁的实现。聚合大量的锁机制实现的共用方法。
0 0
图解ReentrantReadWriteLock读写锁的实现原理(下)
图解ReentrantReadWriteLock读写锁的实现原理
0 0
图解ReentrantReadWriteLock读写锁的实现原理(上)
图解ReentrantReadWriteLock读写锁的实现原理
0 0
ReentrantLock 实现原理(下)
使用 synchronize 来做同步处理时,锁的获取和释放都是隐式的,实现的原理是通过编译后加上不同的机器指令来实现。 而 ReentrantLock 就是一个普通的类,它是基于 AQS(AbstractQueuedSynchronizer)来实现的。 是一个重入锁:一个线程获得了锁之后仍然可以反复的加锁,不会出现自己阻塞自己的情况。 AQS 是 Java 并发包里实现锁、同步的一个重要的基础框架。
0 0
AQS 原理和 ReentrantLock 源码(上)
本文中采用的 jdk 版本为 openjdk-1.8
0 0
AQS 原理和 ReentrantLock 源码(下)
本文中采用的 jdk 版本为 openjdk-1.8
0 0
彻底搞懂AQS
AQS 核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁实现的,即将暂时获取不到锁的线程加入到队列中。
0 0
Java并发同步器AQS
AQS是AbstractQueuedSynchronizer的简写,中文名应该叫抽象队列同步器(我给的名字,哈哈),出生于Java 1.5。 一、什么是同步器 多线程并发的执行,之间通过某种 共享 状态来同步,只有当状态满足 xxxx 条件,才能触发线程执行 xxxx 。
744 0
ReentrantLock实现原理
同步状态 /** * The synchronization state. */ private volatile int state; /** * Returns the current value of synchronization state.
711 0
Java并发框架——AQS之如何使用AQS构建同步器
AQS的设计思想是通过继承的方式提供一个模板让大家可以很容易根据不同场景实现一个富有个性化的同步器。同步器的核心是要管理一个共享状态,通过对状态的控制即可以实现不同的锁机制。
749 0
+关注
在下uptown
练习时长两年半的夹娃练习生
文章
问答
文章排行榜
最热
最新
相关电子书
更多
多线程
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载