显示锁 RenntrantLock
一.继承图
1.Lock接口:lock(),tryLock() ,unlock(),lockInterruptibly() ,newCondition()
- lock():不死不休的获取
- tryLock():浅尝即止
- tryLock(n):过时不侯
- lockInterruptibly():任人摆布(当另外一个线程通知他停止是就不再获取了)
- unlock(): 释放
2.Sync: 继承AbstractQueuedSynchronizer (Node,ConditionObject);AQS 作为模版方法封装了大量锁实现上的封装,其中内部实现了Node作为链表形式
3.Node数据结构:
+------+ prev +-----+ +-----+
head | | <---- | | <---- | | tail
+------+ +-----+ +-----+
4.FairSync:公平锁的实现 (核心tryAcquire CAS时会判断是不是当前队列的头部) 5.NonFairSync:非公平锁实现 CAS成功就获取到锁,当锁刚一释放就cas会造成非公平插队的情况
一. 为什么需要锁
线程安全(原子性,可见性):✅原子性
二.锁的分类
- 公平锁/非公平锁
- 可重入锁
- 独享锁/共享锁
- 互斥锁/读写锁
- 乐观锁/悲观锁 (?)
- 偏向锁/轻量级锁/重量级锁
- 自旋锁
三.锁的实现
ReentrantLock:

3.1:涉及知识AQS ,Condition,FIFO队列,CAS:
1.AQS:java并发控制工具 (1.模版方法设计模式 2.维护链表) 2.CAS:CAS全称 Compare And Swap(比较与交换),由低层硬件确保线程安全(cpu) 3.Condition: 提供多个等待集合,更精确的控制(比如wait/notify的封装实现) 4.FIFO队列:先进先出队列
四总结
原理:
ReentrantLock作为一种独占锁,主要有3个组件
1.waiters一个FIFO队列用于缓冲等待中的线程,
2.owner用于保存锁的持有者
3.count用于实现可重入的效果。
图中比较简单此外还有(公平/非公平两种实现方式)主要是抢锁时判断是否处于队列头部。
了解了以上原理后ReentrantReadWriteLock,就好理解了,首先规则
1.读/写是互斥锁
2.写/写是互斥锁
3.读/读是共享锁
4.当前线程获取到写锁可以降级获取到读锁。
原理将 count 拆分为 readCount/writeCount ,写锁需要记录owner 写锁必须readCount为0才能获取到;而读锁则需要写为0才能获取
最后:第一次写博客有不对之处还请多多指正