【后端面经-Java】Synchronize和ReentrantLock区别

1. 概念介绍

1.1 线程安全锁

Synchronize(同步锁)和ReentrantLock(可重入锁)都是Java中的常用锁,都是用来保证线程安全的。
两者都是同步锁,且都是阻塞同步。

  • 阻塞同步:当一个线程获取锁后,其他线程只能等待(进入阻塞态),等待获取锁的线程释放锁后,其他线程才能获取锁。

    1.2 公平锁

    在多个线程请求资源的时候,如果根据线程请求的顺序来分配资源,那么这个锁就是公平锁,反之就是非公平锁。

    1.3 响应中断/等待可中断

    在线程阻塞期间,阻塞线程等待资源的使用,如果这种等待状态能够被中断,从而释放线程去做其他的事情,这就称为等待可中断

    2. 区别

    2.1 底层实现

    Synchronize是Java的关键字,ReentrantLock是Java类。因此,Synchronize是JVM层面语法层面的同步锁,ReentrantLock是API层面的同步锁

    2.2 锁的用法

  • 设置锁和释放锁:Synchroinze是自动加锁和释放锁的,ReentrantLock设置和释放都需要手动操作;
  • 修饰的对象:Synchroinze可以修饰方法和代码块,ReentrantLock只能修饰代码块

如下代码展示了它们的具体用法:

  • Synchronize作为关键字修饰方法或者代码块即可;

    //synchronized修饰一个方法时,这个方法叫同步方法。
    public synchronized void test() {
    //方法体``
    }
    synchronized(Object) {
    //括号中表示需要锁的对象.
    //线程执行的时候会对Object上锁
    }
  • ReentrantLock的使用需要先创建锁对象,然后在需要加锁的代码块中调用lock()方法加锁,使用完毕后调用unlock()方法释放锁。

    public class LockExample {
      // 创建锁对象
      private final ReentrantLock lock = new ReentrantLock();
      public void method() {
          // 加锁操作
          lock.lock();
          try {
              // ...
          } finally {
              // 释放锁
              lock.unlock();
          }
      }
    }

2.3 锁的特点

ReentrantLock相比于Synchronize,有以下特点:

  • 响应中断:ReentrantLock可以响应中断,也就是在其他线程阻塞期间,可以在长时间无法获取响应的情况下,自行中断等待状态
  • 公平锁:ReentrantLock默认是不公平锁,但是可以设置为公平锁,也就是可以根据线程请求的顺序来分配资源
  • 绑定多个条件:一个ReentrantLock可以同时绑定多个条件,而一个Synchronize锁只能绑定一个条件。

这些特点都是Synchronize锁所不具备的。

2.4 性能比较

Sychronize是JVM层面的同步锁,实现简单,性能较好;
ReentrantLock是API层面的同步锁,需要手动创建和释放锁,性能较差,但是增加了很多特点,灵活性较好。

2.5 适用场景

Synchronize适用于:

  • 简单的同步场景;
  • 对同步性能有较高要求
  • 不需要响应中断、公平锁、绑定多个条件;

ReentrantLock适用于:

  • 需求更复杂的同步场景
  • 对性能要求较低
  • 需要响应中断、公平锁、绑定多个条件;

3. 总结比较

对上述内容进行总结,如下表所示:
【后端面经-Java】Synchronize和ReentrantLock区别_第1张图片

参考文献

  1. Synchronize和ReentrantLock区别
  2. 面试突击:synchronized和ReentrantLock有什么区别?
  3. Java 中 synchronized 和 ReentrantLock 的区别

你可能感兴趣的:(java同步锁后端面试jvm)