ReentrantLock 是JDK提供的可重入锁实现类,可用其替换synchronized来实现锁重入效果;其底层实现主要是依靠AbstractQueuedSynchronizer,本文将通过ReentrantLock来观察AbstractQueuedSynchronizer的运行流程。
这个类在java.util.concurrent.locks包
这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。
CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列,虚拟的双向队列即不存在队列实例,仅存在节点之间的关联关系。
AQS就是基于CLH队列,用volatile修饰共享变量state,线程通过CAS去改变状态符,成功则获取锁成功,失败则进入等待队列,等待被唤醒。
实现了AQS的锁有:自旋锁、互斥锁、读锁写锁、条件产量、信号量、栅栏都是AQS的衍生物
AQS 定义了两种资源共享方式:
1.Exclusive:独占,只有一个线程能执行,如ReentrantLock
2.Share:共享,多个线程可以同时执行,如Semaphore、CountDownLatch、ReadWriteLock,CyclicBarrier
大体意思就是“提供一个框架,用于实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量、事件等)”,AQS不是一个功能完整的类,而是一个提供了一套依赖于FIFO等待队列的流程框架,该框架可用于实现锁等同步器的。AQS中没有使用任何锁相关的API,其实现主要依靠CAS (Compare And Swap),是一个优秀的lock-free 编程实践。
ReentrantLock 是使用AQS实现的,其主要是实现了AQS的tryAcquire
和 tryRelease
方法,且只需要在lock
和unlock
方法中调用一下acquire
和release
方法即可,可以看出AQS非常强大!
https://www.cnblogs.com/fxzou/p/14831007.html
从ReentrantLock看AQS (AbstractQueuedSynchronizer) 运行流程 抽象的队列式同步器