浅谈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. 加锁步骤



同步队列与条件队列

  1. 同步队列存放着竞争同步资源的线程的引用(不是存放线程),而等待队列存放着待唤醒的线程的引用。
  2. 调用condition的await方法,将会使当前线程进入等待队列并释放锁(先加入等待队列再释放锁),同时线程状态转为等待状态
  3. 调用condition的signal方法时,将会把等待队列的首节点移到同步队列的尾部,然后唤醒该节点。
    争抢资源,争抢失败进入同步队列中
  4. 以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是可以重用的。
相关文章
|
3月前
|
存储 Java
JAVA并发编程AQS原理剖析
很多小朋友面试时候,面试官考察并发编程部分,都会被问:说一下AQS原理。面对并发编程基础和面试经验,专栏采用通俗简洁无废话无八股文方式,已陆续梳理分享了《一文看懂全部锁机制》、《JUC包之CAS原理》、《volatile核心原理》、《synchronized全能王的原理》,希望可以帮到大家巩固相关核心技术原理。今天我们聊聊AQS....
图解ReentrantLock底层公平锁和非公平锁实现原理
图解ReentrantLock底层公平锁和非公平锁实现原理
197 0
|
Java 程序员 API
AQS 原理解读
AQS 原理解读
AQS(abstractQueuedSynchronizer)锁实现原理详解
AQS(abstractQueuedSynchronizer)抽象队列同步器。其本身是一个抽象类,提供lock锁的实现。聚合大量的锁机制实现的共用方法。
156 0
图解ReentrantReadWriteLock读写锁的实现原理(下)
图解ReentrantReadWriteLock读写锁的实现原理
132 0
图解ReentrantReadWriteLock读写锁的实现原理(下)
|
Java API
图解ReentrantReadWriteLock读写锁的实现原理(上)
图解ReentrantReadWriteLock读写锁的实现原理
214 0
图解ReentrantReadWriteLock读写锁的实现原理(上)
|
算法 Java API
深入浅出理解Java并发AQS的共享锁模式
深入浅出理解Java并发AQS的共享锁模式
139 0
深入浅出理解Java并发AQS的共享锁模式
|
安全 Java
java并发原理实战(9)--手动实现一个可重入锁
java并发原理实战(9)--手动实现一个可重入锁
129 0
java并发原理实战(9)--手动实现一个可重入锁
|
存储 Java
Java并发之AQS源码分析(一)
AQS 全称是 AbstractQueuedSynchronizer,顾名思义,是一个用来构建锁和同步器的框架,它底层用了 CAS 技术来保证操作的原子性,同时利用 FIFO 队列实现线程间的锁竞争,将基础的同步相关抽象细节放在 AQS,这也是 ReentrantLock、CountDownLatch 等同步工具实现同步的底层实现机制。它能够成为实现大部分同步需求的基础,也是 J.U.C 并发包同步的核心基础组件。
127 0
Java并发之AQS源码分析(一)