synchronized和ReentrantLock有什么区别?


一、synchronized和ReentrantLock有什么区别?

synchronized和ReentrantLock的区别有以下几点:

  • 底层实现:synchronized是Java关键字,ReentrantLock是Java API
  • 手动获取/释放:synchronized不需要手动获取/释放锁,ReentrantLock需要手动获取/释放锁
  • 是否公平锁:synchronized只有非公平锁,ReentrantLock有公平锁和非公平锁
  • 实现原理:synchronized的实现涉及到锁的升级,具体为无锁、偏向锁、轻量级锁、重量级锁等;ReentrantLocal的实现是通过CAS自旋机制保证线程操作的原子性和volatile保证数据可见性以实现锁的功能
  • 是否可中断:synchronized是不可中断类型的锁,ReentrantLock则可以中断,可通过trylock(long timeout, TimeUnit unit设置超时方法或者将lockInterruptibly()放到代码块中,调用interrupt方法进行中断
  • 是否可重入:synchronized和ReentrantLock都是可重入的
  • 锁状态:synchronized是通过state标识锁的状态,ReentrantLock锁的是对象,对应的锁信息保存在对象头中

二、Q&A

1、什么是可重入锁?

可重入锁,也叫做递归锁,指的是一个线程在获取一个对象锁后,如果在还没释放锁之前还想再获得该锁,那么直接可以获得。相反的,如果不是可重入锁,那么重复获得锁的时候就会出现死锁

synchronizedReentrantLock都是可重入锁,简单举个例子:

public class SynchronizedDemo {
    public synchronized void method1() {
        method2();
    }
    
    public synchronized void method2() {
        // ...
    }
}

解析method1()method2()都用了synchronized修饰,所以他们锁住的是当前对象this,当method1()调用method2()时,判断两个方法都是被当前对象占有,所以可以直接获得锁并执行

2、什么是公平锁和非公平锁?

简单来说,公平锁就是线程按顺序获得锁(先等待先获得),非公平锁就是随机获得锁(可能造成某个线程等待太久)。

synchronized是非公平锁,ReentrantLock是公平锁,通过ReentrantLock(boolean fair)构造方法来指定。

3、什么是可中断锁和不可中断锁?

synchronized是不可中断锁,ReentrantLock是可中断锁,他们之间的区别是:

  • 可中断锁:获取锁的过程中可以被中断,不需要一直等待到获取锁之后才能执行其他逻辑
  • 不可中断锁:一旦尝试获取锁,就必须等待到获取锁之后才能执行其他逻辑

文章作者: GaryLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GaryLee !
  目录