详解JUC之锁——Lock与AQS(02)
2017-05-11 17:07
267 查看
前言
在详解JUC之锁——概述(01)中我对JUC中的锁进行了概述,下面我就介绍一下它们的根基Lock接口和
AQS类
Lock
看名字就知道Lock接口就是JUC中锁的顶级接口,支持语义不同的锁规则,比如说公平锁和非公平锁,独占锁(也可以叫互斥锁)和共享锁等。
它最主要的两个方法就是
lock()和
unlock(),一看就知道是获取锁和释放锁。
还有一个比较有趣的方法是
boolean tryLock(long time, TimeUnit unit)方法,这个方法没有
lock()方法那么死心眼,它在尝试获取锁,获取到了就返回
true,一段时间获取不到就算了,返回一个
false。
当然了,还有
Condition newCondition()方法,返回与之关联的
Condition对象
AbstractQueuedSynchronizer
AbstractQueuedSynchronizer就是大名鼎鼎的AQS类,怎么说呢,这个类就是JUC锁的根基,是JUC中不同锁的共同抽象类,锁的许多公共方法都是在这个类中实现的,我给你看看它类继承结构你就知道了
有没有发现,无论是带有
Lock后缀的类如
ReentrantLock还是不带
Lock后缀的类如
Semaphore它们里面的内部类
Sync都继承了
AQS。其实JUC中的各种锁只是一个表面装饰,它们里面真正实现功能的还是
Sync。
我再来给你看一个比根基更根基的东西,那就是
AQS类的一个成员变量
state
/** * The synchronization state. */ private volatile int state;
看注释说这个就是同步状态,可能到现在你还没有概念。那我问你,锁最主要的操作是什么?不就是获取锁和释放锁嘛!!上面我讲了JUC中不同锁的很多公共方法是在
AQS类实现的,其中就有获取锁和释放锁的方法,而我可以大声地告诉你,JUC中所有锁的获取锁和释放锁操作都是围绕着这个同步状态
state进行加减操作。每次一个线程获取到锁即对应着这个
state加1,释放锁就对应着这个
state减1(
Semaphore就特殊点,它能加n和减n),
state为0的时候代表锁空闲。
公平锁和非公平锁
从上面我给出的AQS的继承结构图你会发现,很多锁的名叫
Sync的内部类继承了
AQS类,而这个
Sync又分别有
FairSync和
NonfairSync类继承它,看名字就知道它们分别是公平锁和非公平锁了。
那公不公平的准则又是什么呢?
说到这个得先介绍一下CLH队列,CLH队列是AQS中“等待锁”的线程队列,比如说独占锁被一个线程占用着,其它线程就必须等待咯,这些线程就是在CLH队列等待的。这个队列的是用链表实现的,你可以看到
AQS类有个内部类
Node,这个就是链表的节点。CLH是通过自旋+CAS保证节点插入和移除的原子性(这个我在介绍原子类的时候说过类似的),就是说往里面插入或移除一个节点的时候,在并发条件下不会有问题。
至于CLH是什么意思,在
Node的注释上有
"CLH" (Craig, Landin, and Hagersten) lock queue,目测是三个人的名字缩写,应该是造出它的人吧。
那现在就可以回答公平的准则了。所谓公平,就是大家排队,是按照CLH队列先来先得的规则,即使锁没被任何线程持有,只要一个线程不是处于队头,它也会乖乖地等,公平地获取锁;非公平,那就是插队咯,当线程要获取锁时,它会无视CLH等待队列而直接获取锁,如果锁没有被任何线程持有,那不管它在CLH的那个角落,它都直接获取锁,没什么道德可言。
AbstractQueuedLongSynchronizer和AbstractOwnableSynchronizer
至于AbstractQueuedLongSynchronizer类跟
AbstractQueuedSynchronizer类差不多,只不过它里面的
state是
long类型的,而
AbstractQueuedSynchronizer的是
int类型的,而且它们都继承了
AbstractOwnableSynchronizer类——一个记录当前持有独占锁的线程的抽象类,这个类很简单,维护一个
Thread类型变量,这个应该就是记录当前持有独占锁的线程,然后提供它的
getter和
setter方法,它虽然是一个抽象类,但是里面并没有抽象方法。
相关文章推荐
- JAVA多线程系列--ReentrantLock实现原理-AQS详解
- Java并发编程札记-(四)JUC锁-02Lock与ReentrantLock
- NET多线程同步方法详解(二):互斥锁(lock) 收藏
- [倾情原创] 锁·二则——lock关键字详解
- c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex
- v$lock type字段详解
- c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex
- lock关键字详解
- 转:c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex
- MVC详解:了解真正所谓的"框架"(http://vipnews.csdn.net/newscontent.aspx?pointid=2009_02_01_144216610)
- c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex
- [倾情原创] 锁·二则——lock关键字详解
- c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex
- c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex(ZT)
- linux vlock(virtual console lock) 命令详解
- c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex(ZT)
- 指针详解-02
- c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex
- NET多线程同步方法详解(三):读写锁(ReadWriteLock) 收藏
- c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex