Appearance
Sychronized的锁升级过程是怎样的
- 偏向锁: 在锁对象的对象头中记录一下当前获取到该锁线程ID,该线程下次如果又来获取该锁就可以直接获取到,也就是支持锁重入
- 轻量级锁:由偏向锁升级而来,当一个线程获取到锁后,此时这把锁是偏向锁,此时如果有第二个线程来竞争锁,偏向锁就会升级为轻量级锁,之所以叫轻量级锁,是为了和重量级锁区分开来,轻量级锁底层是通过自旋来实现的,并不会阻塞线程.
- 如果自旋次数过多任然没有获取到锁,则会升级为重量级锁,重量级锁会导致线程阻塞.
- 自旋锁: 自旋锁就是线程在获取锁的过程中,不会去阻塞线程,也就无所谓唤醒线程,阻塞和唤醒这两个步骤都是需要操作系统去进行的,比较消耗时间,自旋锁是线程通过CAS获取预期的一个标记,如果没有获取到,则继续循环获取,如果获取到了则表示获取到了锁,这个过程线程一直在运行中,相对而言没有使用太多的操作系统资源,比较轻量.
Sychronized和ReentrantLock有哪些不同点
sychronized | ReentrantLock |
---|---|
Java中的关键字 | JDK提供的类 |
自动加锁和释放锁 | 需要手动加锁和释放锁 |
JVM层面锁 | API层面锁(JUC) |
非公平锁 | 均有 |
锁的是对象,锁信息保存在对象头中 | int类型的state表示来标识锁的状态 |
底层有锁升级的过程 | 没有锁升级的过程 |
ReentrantLock 分为公平锁和非公平锁,那么底层是如何实现的呢
- 首先不管是公平锁还是非公平锁,它们底层实现都会使用AQS队列来进行排队,它们的区别在于线程在使用lock方法加锁时:
- 如果是公平锁,会先检查AQS队列中是否存在线程在排队,如果有线程在排队,则当前线程也进行排队
- 如果是非公平锁,则不会检查是否有线程在排队,而是直接竞争锁(插队),如果没有竞争到锁,也会进行排队
- ReentrantLock是可重入锁,公平锁和非公平锁都是可重入的