Skip to content

Sychronized的锁升级过程是怎样的

  1. 偏向锁: 在锁对象的对象头中记录一下当前获取到该锁线程ID,该线程下次如果又来获取该锁就可以直接获取到,也就是支持锁重入
  2. 轻量级锁:由偏向锁升级而来,当一个线程获取到锁后,此时这把锁是偏向锁,此时如果有第二个线程来竞争锁,偏向锁就会升级为轻量级锁,之所以叫轻量级锁,是为了和重量级锁区分开来,轻量级锁底层是通过自旋来实现的,并不会阻塞线程.
  3. 如果自旋次数过多任然没有获取到锁,则会升级为重量级锁,重量级锁会导致线程阻塞.
  4. 自旋锁: 自旋锁就是线程在获取锁的过程中,不会去阻塞线程,也就无所谓唤醒线程,阻塞和唤醒这两个步骤都是需要操作系统去进行的,比较消耗时间,自旋锁是线程通过CAS获取预期的一个标记,如果没有获取到,则继续循环获取,如果获取到了则表示获取到了锁,这个过程线程一直在运行中,相对而言没有使用太多的操作系统资源,比较轻量.

Sychronized和ReentrantLock有哪些不同点

sychronizedReentrantLock
Java中的关键字JDK提供的类
自动加锁和释放锁需要手动加锁和释放锁
JVM层面锁API层面锁(JUC)
非公平锁均有
锁的是对象,锁信息保存在对象头中int类型的state表示来标识锁的状态
底层有锁升级的过程没有锁升级的过程

ReentrantLock 分为公平锁和非公平锁,那么底层是如何实现的呢

  • 首先不管是公平锁还是非公平锁,它们底层实现都会使用AQS队列来进行排队,它们的区别在于线程在使用lock方法加锁时:
    • 如果是公平锁,会先检查AQS队列中是否存在线程在排队,如果有线程在排队,则当前线程也进行排队
    • 如果是非公平锁,则不会检查是否有线程在排队,而是直接竞争锁(插队),如果没有竞争到锁,也会进行排队
  • ReentrantLock是可重入锁,公平锁和非公平锁都是可重入的