AQS

组成

  1. 同步队列:链表结构,先进先出,尾部入队,头部出队;
  2. state:同步器状态,独占模式下,state=0 代表可以获取锁,state> 0 代表锁被占用;
  3. Node head:头节点,第一个节点入队得适合会初始化一个头节点,然后令 head = tail;
  4. Node tail:尾节点,获取不到锁时,会从尾部入队一个节点,同时更新该节点为尾节点;

AQS定义两种资源共享方式: Exclusive:独占,只有一个线程能执行,如ReentrantLock Share:共享,多个线程可同时执行,如Semaphore/CountDownLatch

AQS已经在顶层实现好了。自定义同步器实现时主要实现以下几种方法:

  • isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。
  • tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
  • tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
  • tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
  • tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false。

以ReentrantLock为例,state初始化为0,表示未锁定状态。A线程lock()时,会调用tryAcquire()独占该锁并将state+1。此后,其他线程再tryAcquire()时就会失败,直到A线程unlock()到state=0(即释放锁)为止,其它线程才有机会获取该锁。当然,释放锁之前,A线程自己是可以重复获取此锁的(state会累加),这就是可重入的概念。但要注意,获取多少次就要释放多么次,这样才能保证state是能回到零态的。

再以CountDownLatch以例,任务分为N个子线程去执行,state也初始化为N(注意N要与线程个数一致)。这N个子线程是并行执行的,每个子线程执行完后countDown()一次,state会CAS减1。等到所有子线程都执行完后(即state=0),会unpark()主调用线程,然后主调用线程就会从await()函数返回,继续后余动作。

一般来说,自定义同步器要么是独占方法,要么是共享方式,他们也只需实现tryAcquire-tryRelease、tryAcquireShared-tryReleaseShared中的一种即可。但AQS也支持自定义同步器同时实现独占和共享两种方式,如ReentrantReadWriteLock。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java线程池

    线程池的核心实现类,基于ThreadPoolExecutor可以实现满足不同场景的线程池

    spilledyear
  • Java基础

    HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap元素插入的顺序,也就是无序,而LinkedHashMap是有序的。

    spilledyear
  • AQS之独占锁

    AbstractQueuedSynchronizer,抽象类,模板模式,子类通过实现其模板方法,从而实现不同的同步器,例如: ReentrantLock Ree...

    spilledyear
  • Java Concurrent AQS原理&源码概要(Java 10)

    开始说AQS之前,继续说上一篇没说完的建议,相对于看一些不知道时效性的blog,说实话,理解一个知识点最简便的方式就是看论文及源码实现了,解决一个问题最好的方式...

    邹志全
  • 高并发编程-CyclicBarrier深入解析

    CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到所有线程都到达某个公共屏障点(也可以叫同步点),即相互等待的线程都完成调用await方法...

    JavaQ
  • 进程、线程、协程到底是个什么东西?

    不管是上大学课程《操作系统》,还是找工作面试,还是日常工作大家交流中,都离不开进程和线程,有些同学可能还会听说过协程。那他们到底是什么呢?他们之间有什么关系呢...

    会呼吸的Coder
  • Java并发编程--Lock

      Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。synchronized方法或代码块的使用提供了对与每个对象相关的...

    在周末
  • 关于ThreadLocal内存泄露的备忘

    还记得第一次接触到ThreadLocal可能导致内存泄露的问题是有一次面试的时候被问到了ThreadLocal的缺陷是什么。当然由于后来没有面试官的联系方式很遗...

    哲洛不闹
  • 你必须要知道的热门 ReentrantLock 及 AQS 的实现原理

    提到 JAVA 加锁,我们通常会想到 synchronized 关键字或者是 Java Concurrent Util(后面简称JCU)包下面的 Lock,今天...

    lyb-geek
  • AbstractQueuedSynchronizer超详细原理解析

     今天我们来研究学习一下AbstractQueuedSynchronizer类的相关原理,java.util.concurrent包中很多类都依赖于这个类所提供...

    程序员历小冰

扫码关注云+社区

领取腾讯云代金券