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. 总结比拟

对上述内容进行总结,如下表所示:

参考文献

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