.
ReentrantLock
- ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”
- ReentrantLock在同一个时间点只能被一个线程锁持有,“可重入”意为ReentrantLock锁可以被同一个线程多次获取
- 公平锁与非公平锁
- 公平锁:就是谁等待时间最长,谁就先获取锁,ReentrantLock中用AQS队列实现
- 非公平锁:随机获取,CPU时间片轮询到哪个线程,哪个线程就能获取锁
使用语法
1 | Lock lock=new ReentrantLock(); |
构造方法
1 | //默认创建非公平锁 |
NonfairSync & FairSync
都是基于AQS队列(AbstractQueuedSynchronizer
)来管理获取该锁的所有线程
它是基于FIFO实现的等待队列,AQS队列基于双向链表,如果一个线程获取锁就直接成功,如果失败了就将其放入等待队列当中
获取锁
1 | public void lock() { |
- CAS操作抢占锁,抢占成功则将持有数的设为1,将线程信息记录到锁当中
- 如果当前线程已经获取了锁,将持有数+1
- 抢占不成功,新建一个Node插入到当前AQS队列的尾部
释放锁
- 若当前线程是锁的持有者(与锁中的信息进行比较),将持有数-1。当状态值减为0时,释放锁
- 若当前线程不是锁的持有者抛出
IllegalMonitorStateException
synchronized
JDK1.6后对synchronized进行了优化,不再是重量级锁
主要存在四种状态,依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态。但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级