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

端面,java,synchronize,reentrantlock,区别 · 浏览次数 : 41

小编点评

**目录** 1. 概念介绍 1.1 线程安全锁 1.2 公平锁 1.3 响应中断/等待可中断 2. 区别 2.1 底层实现Synchronize是Java的关键字 2.2 锁的用法设置锁和释放锁 3. 总结比较 **1. 概念介绍** **1.1 线程安全锁Synchronize(同步锁)和ReentrantLock(可重入锁)**都是Java中的常用锁,都是用来保证线程安全的。两者都是同步锁,且都是阻塞同步。阻塞同步:当一个线程获取锁后,其他线程只能等待(进入阻塞态),等待获取锁的线程释放锁后,其他线程才能获取锁。 **1.2 公平锁在多个线程请求资源的时候,如果根据线程请求的顺序来分配资源,那么这个锁就是公平锁,反之就是非公平锁。 **1.3 响应中断/等待可中断在线程阻塞期间,阻塞线程等待资源的使用,如果这种等待状态能够被中断,从而释放线程去做其他的事情,这就称为等待可中断。 **2. 区别** **2.1 底层实现Synchronize是Java的关键字** **2.2 锁的用法设置锁和释放锁:** * **Synchroinze**是自动加锁和释放锁的,**ReentrantLock**设置和释放都需要手动操作; * **修饰对象:**`synchronize`可以修饰方法和代码块,**ReentrantLock**只能修饰代码块如下代码展示了它们的具体用法: ```java Synchronize作为关键字修饰方法或代码块即可; // synchronized修饰一个方法时,这个方法叫同步方法。 public synchronized void test() { //方法体 } ``` **2.3 锁的特点** **ReentrantLock**相比于**Synchronize**,有以下特点: * **响应中断:****ReentrantLock**可以响应中断,也就是在其他线程阻塞期间,可以在长时间无法获取响应的情况下,自行中断等待状态公平锁:**ReentrantLock**默认是不公平锁,但是可以设置为公平锁,也就是可以根据线程请求的顺序来分配资源绑定多个条件。 * **公平锁:****ReentrantLock**默认是不公平锁,但可以设置为公平锁,也就是可以根据线程请求的顺序来分配资源绑定多个条件。 **2.4 性能比较** **Sychronize**适用于: * **简单的同步场景**; * **对同步性能有较高要求**不需要响应中断、公平锁、绑定多个条件; **2.5 适用场景** **ReentrantLock**适用于: * **需求更复杂的同步场景对性能要求较低**需要响应中断、公平锁、绑定多个条件。

正文

1. 概念介绍

1.1 线程安全锁

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

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

1.2 公平锁

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

1.3 响应中断/等待可中断

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

2. 区别

2.1 底层实现

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

2.2 锁的用法

  1. 设置锁和释放锁:Synchroinze是自动加锁和释放锁的,ReentrantLock设置和释放都需要手动操作;
  2. 修饰的对象: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 的区别

与【后端面经-Java】Synchronize和ReentrantLock区别相似的内容:

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

本文介绍了Synchronize和ReentrantLock同步锁的相似和不同点,并指出两者的主要特点和适用场景。

【后端面经-Java】Java创建线程的方法简介

本文简要介绍了java中创建线程的四种方式,并介绍了线程概念,适合新手阅读。

【后端面经-java】java线程池满的处理策略

本文对java线程池做了具体介绍,并且讨论了java线程池满了之后的拒绝策略。

【后端面经-Java】HashMap详解

本文详细介绍了hashmap,包括基本概念、hashmap数据结构、关键变量和重要方法,并且结合源码进行分析。

【后端面经-Java】AQS详解

本文介绍了AQS的核心思想、基本架构、实现方法,并对框架中的重要源码方法进行介绍和分析

【后端面经-Java】公平锁和加锁流程

本文主要介绍了公平锁和非公平锁的概念和区别,并且结合Reentranslock锁的源码对加锁机制进行分析。

【后端面经-Java】I/O多路复用 简录

本文主要介绍了Java当中常见的几种IO模型,介绍其运行机制和实际缺点,并进行技术对比,对于IO多路复用的实现方式进行分析。

【后端面经-Java】JVM内存分区详解

本文主要介绍了JVM内存分区的基本情况,着重介绍了栈、堆、方法区的分区情况,并给出实际代码解释内存分配的过程。

【后端面经-Java】JVM垃圾回收机制

本文对JVM垃圾回收机制做了详细解释,从"where"、"which"、"when"、"why"、"how"、"who"的角度,重点介绍JVM垃圾回收机制的触发机制、垃圾判断算法、垃圾回收算法和垃圾回收机制。

【后端面经-Java】String与StringBuffer与StringBuilder的比较

本文从String、StringBuffer、StringBuilder三者的特性出发,详细介绍三者的不同之处。