ReentrantLock(独占式锁)
1.重入锁的实现原理
表示能够对共享资源能够重复加锁,即当前线程获取该锁时再次获取不会被阻塞
核心方法:nonfairTryAcquire
2.公平锁的实现原理
加入hasQueuedPredecessors的逻辑判断,用来 判断当前节点在同步队列中是否有前驱节点的判断
3.非公平锁的实现原理
默认非公平锁
4.公平锁和非公平锁的比较
1.公平锁每次都是从同步队列中的第一个节点,保证请求资源时间上的绝对顺序,非公平锁有可能刚 释放锁的线程下次继续获取该锁,则有可能导致其他线程永远无法获取到锁,造成“饥饿”现象。
2.公平锁为了保证时间上的绝对顺序,需要频繁的上下文切换,而非公平锁会降低一定的上下文 切换,降低性能开销。因此,ReetrantLock默认选择的是非公平锁,保证了系统更大的吞吐量
ReentrantReadWriteLock(读写锁)
1.如何表示读写状态的
同步状态int类型变量state:
- 低16位用来表示写锁的获取次数
- 高16位用来表示读锁的获取次数
2.WriteLock的获取和释放
当ReadLock已经被其他线程获取或者WriteLock被其他线程获取,当前线程WriteLock失败;否则获取成功,支持重入性,WirteLock释放时将写状态通过CAS操作减一。
3.ReadLock的获取和释放
当WriteLock已经被其他线程获取的话,ReadLock获取失败;否则获取成功。支持重入性,通过CAS操作将读状态减1。
4.锁降级策略
按照WriteLock.lock() --> ReadLock.lock() -->WriteLock.unlock()的顺序,WriteLock会降级为ReadLock。
5.生成Condition等待队列
WriteLock可以通过newCondition方法生成Condition 等待队列,而ReadLock无法生成Condition等待队列
6.应用场景
适用于读多写少的应用场景,比如缓存设计上
Condition机制
简介:
Object的wait和notify/notifyAll是与对象监视器配合完成线程间的等待/通知机制,而Condition与 Lock配合完成等待通知机制,前者是java底层级别的,后者是语言级别的,具有更高的可控性和扩展性
1.与Object的wait/notify机制相比具有的特性
- Condition能够支持不响应中断,而Object不支持
- Lock能够支持多个Condition等待队列,而Object只能支持一个
- Condition能够支持设置超时时间的await,而Object不能
2.与Object的wait/notify相对应的方法
- 针对Object的wait方法:await,awaitNanos,....
- 针对Object的notify/notifyAll方法:signal,signalAll方法
3.底层数据结构
复用AQS的Node类,由不带头结点的链表实现的队列
4.await实现原理
将调用await方法的线程封装成Node,尾插入到同步队列中,并通过 LockSupport.park方法将当前线程至于WAITING状态,直至其他线程 通过signal/signalAll方法将其移入到同步队列中,时期有机会在同步 队列中通过自旋获取到Lock,从而当前线程才能从await方法处退出
5.signal/signalAll实现原理
将等待队列的队头结点移入到同步队列中
6.await和signal/signalAll的结合使用
7.transient
生命周期:调用者的内存中而不会写到磁盘里持久化
原理:组织实例中的用此关键字声明的变量持久化,当对象被反序列化时,实例变量不会被持久化和恢复