【JAVA面试题】探索多线程同步:ReentrantLock与synchronized的对比解析

news2024/11/18 8:33:51

程序员如何搞副业?

文章目录

    • 程序员如何搞副业?
      • 强烈推荐
      • 引言:
      • ReentrantLock介绍
        • 可重入性(Reentrancy):
        • 公平性(Fairness):
        • 条件变量(Condition):
        • 可中断性(Interruption):
        • 超时获取(Timeout):
      • synchronized 的介绍
        • 互斥性(Mutual Exclusion):
        • 可见性(Visibility):
        • 原子性(Atomicity):
        • 隐式锁和释放:
      • ReentrantLock 和synchronized 的异同点
        • 相同点:
        • 不同点:
      • ReentrantLock 和synchronized 的应用场景
        • `ReentrantLock` 的场景:
        • 适合使用 `synchronized` 的场景:
      • ReentrantLock 和synchronized 的应用实例
        • 使用 `ReentrantLock` 实现线程同步:
        • 使用 `synchronized` 实现线程同步:
      • 总结:
      • 强烈推荐
      • 专栏集锦
      • 写在最后

579a429daf314744b995f37351b46548

强烈推荐

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能

b004071ozy_05_amzn


引言:

在多线程编程中,确保共享资源的安全访问是至关重要的。

为了避免数据竞争和不确定的结果,我们需要使用适当的同步机制来保护共享资源。

Java 中提供了两种主要的线程同步机制:ReentrantLocksynchronized

虽然它们都可以实现线程同步,但在具体的应用中,我们需要根据需求和场景来选择合适的方法。

本文将介绍 ReentrantLocksynchronized 的异同点,并通过示例演示它们的应用场景和用法。


ReentrantLock介绍

ReentrantLock 是 Java 中用于实现锁的一个类,它提供了与 synchronized 关键字类似的功能,但更加灵活和强大。与 synchronized 相比,ReentrantLock 提供了更多的操作和控制选项。

  1. 可重入性(Reentrancy):

    synchronized 类似,ReentrantLock 支持线程的可重入性,即同一个线程可以多次获取同一个锁而不会造成死锁。

  2. 公平性(Fairness):

    ReentrantLock 可以选择是否公平地进行锁的获取。公平锁是指锁的获取按照线程请求的顺序来分配,而非公平锁则不保证这种顺序。公平锁可以避免某些线程长时间被阻塞的情况,但会带来一些性能损耗。

  3. 条件变量(Condition):

    ReentrantLock 提供了 Condition 接口,可以用来在锁上等待或者唤醒特定的条件。这使得在某些情况下,我们可以更加灵活地控制线程的等待和唤醒。

  4. 可中断性(Interruption):

    synchronized 不同,ReentrantLock 提供了可中断的获取锁的方法。即在等待锁的过程中,线程可以响应中断信号而提前退出等待。

  5. 超时获取(Timeout):

    ReentrantLock 提供了尝试获取锁的方法,允许线程在一定的时间内尝试获取锁,如果超过指定的时间仍未获取到锁,则返回失败。

使用 ReentrantLock 需要手动进行锁的获取和释放,相对于 synchronized 更加灵活,但也需要更加小心地处理锁的获取和释放,以避免出现死锁等问题。


synchronized 的介绍

synchronized 是 Java 中用于实现线程同步的关键字,可以用来确保多个线程不会同时访问共享资源,从而避免数据竞争和不确定的结果。

  1. 互斥性(Mutual Exclusion):

    synchronized 关键字可以应用于方法或代码块,确保同一时刻只有一个线程可以执行被 synchronized 修饰的代码,其他线程必须等待当前线程执行完毕才能执行该代码块或方法。

  2. 可见性(Visibility):

    通过synchronized关键字,线程在释放锁时会将修改的变量值刷新到主内存,从而保证了在不同线程间的可见性,即一个线程对共享变量的修改对其他线程是可见的。

  3. 原子性(Atomicity):

    synchronized 块中的代码被视为一个不可分割的整体,称为原子操作。这确保了在同一时刻只有一个线程可以执行 synchronized 块中的代码,从而避免了因多线程并发访问而导致的数据不一致问题。

  4. 隐式锁和释放:

    ReentrantLock 不同,synchronized 使用起来更加简洁,不需要显式地获取和释放锁,锁的获取和释放由 JVM 隐式地管理。

虽然 synchronized 简单易用,但也有一些限制,例如无法设置超时、不支持非块结构的条件等待。在性能方面,synchronized 相对于 ReentrantLock 可能会有一些性能开销,尤其是在高并发场景下。


ReentrantLock 和synchronized 的异同点

ReentrantLocksynchronized 都可以用于实现线程同步,但在实现细节、功能和使用方式上有一些异同点:

相同点:
  1. 实现线程同步

    ReentrantLocksynchronized 都可以确保多个线程之间对共享资源的访问是线程安全的,避免了数据竞争和不确定的结果。

  2. 可重入性

    两者都支持线程的可重入性,即同一个线程可以多次获取同一个锁而不会造成死锁。

  3. 内置的可见性和原子性

    无论是 ReentrantLock 还是 synchronized,在释放锁时都会将修改的变量值刷新到主内存,从而保证了在不同线程间的可见性,并且锁的获取和释放都是原子操作。

不同点:
  1. 灵活性和控制性

    • ReentrantLock 相比 synchronized 更加灵活,提供了更多的操作和控制选项,例如可中断性、公平性、超时获取等,以及条件变量的支持。
    • synchronized 使用起来更加简洁,不需要显式地获取和释放锁,锁的管理由 JVM 隐式地完成。
  2. 可中断性

    • ReentrantLock 支持可中断的锁获取操作,即在等待锁的过程中可以响应中断信号而提前退出等待。
    • synchronized 不支持可中断性,一旦线程进入等待状态,只能等待锁的释放。
  3. 公平性

    • ReentrantLock 可以选择是否公平地进行锁的获取,即锁的获取按照线程请求的顺序来分配。
    • synchronized 不提供公平性选项,它总是非公平的。
  4. 性能开销

    • 在性能方面,一般情况下 synchronized 的性能优于 ReentrantLock,因为 synchronized 的实现经过 JVM 的优化,而 ReentrantLock 的实现较为复杂,可能会有一些额外的性能开销。但在高并发场景下,ReentrantLock 的性能可能会更好,因为它提供了更多的控制选项,可以更好地适应特定的应用场景。

综上所述,选择使用 ReentrantLock 还是 synchronized 取决于具体的需求和应用场景,通常情况下建议优先考虑使用 synchronized,除非需要 ReentrantLock 提供的额外功能和灵活性。


ReentrantLock 和synchronized 的应用场景

ReentrantLocksynchronized 都可以用于实现线程同步,但它们的应用场景有一些差异:

ReentrantLock 的场景:
  1. 需要更灵活的锁控制

    如果需要更多的锁控制选项,例如可中断性、公平性、超时获取等,ReentrantLock 是一个更好的选择。例如,在某些情况下,需要能够在等待锁的过程中响应中断信号而提前退出等待,这时候就可以使用 ReentrantLock 的可中断锁。

  2. 需要实现读写分离锁

    ReentrantReadWriteLockReentrantLock 的一个扩展,提供了读写分离锁的功能,适用于读多写少的场景。

  3. 需要手动释放锁

    ReentrantLock 需要手动进行锁的获取和释放,这种手动释放锁的方式可能在某些场景下更加灵活,但也需要更小心地处理锁的获取和释放,以避免出现死锁等问题。

适合使用 synchronized 的场景:
  1. 简单的同步需求

    对于简单的同步需求,例如对单个方法或代码块进行同步,没有额外的锁控制需求,使用 synchronized 更加简洁和方便。

  2. 性能要求不是关键因素

    在性能要求不是关键因素的情况下,使用 synchronized 更加方便,因为它不需要额外的锁管理开销,而且 JVM 对其进行了优化。

  3. 易于理解和维护

    synchronized 使用起来更加简单,不需要手动释放锁,对于代码的可读性和维护性更加友好。

选择使用 ReentrantLock 还是 synchronized 取决于具体的需求和应用场景。

通常情况下,如果没有特殊的锁控制需求,并且性能要求不是关键因素,建议优先考虑使用 synchronized,因为它更简单、更方便。

而在需要更灵活的锁控制、或者性能要求较高的场景下,可以考虑使用 ReentrantLock


ReentrantLock 和synchronized 的应用实例

使用 ReentrantLock 实现线程同步:
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;

    public void increment() {
        lock.lock(); // 获取锁
        try {
            count++; // 临界区代码
        } finally {
            lock.unlock(); // 释放锁
        }
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) {
        ReentrantLockExample example = new ReentrantLockExample();

        // 创建多个线程并启动
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    example.increment(); // 调用 increment 方法
                }
            }).start();
        }

        // 等待所有线程执行完毕
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 输出最终的 count 值
        System.out.println("Final count: " + example.getCount());
    }
}
使用 synchronized 实现线程同步:
public class SynchronizedExample {
    private int count = 0;

    public synchronized void increment() { // 使用 synchronized 关键字修饰方法
        count++; // 临界区代码
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) {
        SynchronizedExample example = new SynchronizedExample();

        // 创建多个线程并启动
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    example.increment(); // 调用 increment 方法
                }
            }).start();
        }

        // 等待所有线程执行完毕
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 输出最终的 count 值
        System.out.println("Final count: " + example.getCount());
    }
}

总结:

在多线程编程中,选择合适的线程同步机制对于程序的性能和正确性至关重要。

ReentrantLocksynchronized 都是有效的线程同步机制,每种机制都有其优势和适用场景。

在实际开发中,我们应该根据具体的需求和场景来选择合适的机制,并且在编写多线程代码时,始终注意避免死锁和性能瓶颈等问题,以确保程序的正确性和高效性。


强烈推荐

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能

b004071ozy_05_amzn

专栏集锦

大佬们可以收藏以备不时之需:

Spring Boot 专栏:http://t.csdnimg.cn/peKde

ChatGPT 专栏:http://t.csdnimg.cn/cU0na

Java 专栏:http://t.csdnimg.cn/YUz5e

Go 专栏:http://t.csdnimg.cn/Jfryo

Netty 专栏:http://t.csdnimg.cn/0Mp1H

Redis 专栏:http://t.csdnimg.cn/JuTue

Mysql 专栏:http://t.csdnimg.cn/p1zU9

架构之路 专栏:http://t.csdnimg.cn/bXAPS


写在最后

感谢您的支持和鼓励! 😊🙏

如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,java基础面试题, netty, spring boot, spring cloud等系列文章,一系列干货随时送达!

csdn-end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1614309.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flume在大数据集群下的配置以及监控工具Ganglia的部署安装

前提&#xff1a;需要有三台虚拟机&#xff08;hadoop102,103,104&#xff09;配置好相关基础环境 安装 将安装包上传到/opt/software中 tar -zxf /opt/software/apache-flume-1.9.0-bin.tar.gz -C /opt/module/修改 apache-flume-1.9.0-bin 的名称为 flume mv /opt/module/…

交易猫、闲鱼、转转圈号客服台V4-V5源码

新增转转订单客服、闲鱼。各种反炸客服&#xff0c;更换了UI&#xff01;

RAG技术从入门到精通

LLM之RAG技术从入门到精通 RAG技术介绍诞生背景定义 RAG与微调RAG流程架构RAG三种范式Naive RAGAdvanced RAG预检索过程嵌入后期检索过程RAG管道优化 Modular RAG RAG工作流程企业知识问答知识库RAG评估评价方法独立评估端到端评估 关键指标和能力 RAG优化RAG在企业知识库应用下…

OpenHarmony多媒体-mp3agic

简介 mp3agic 用于读取 mp3 文件和读取/操作 ID3 标签&#xff08;ID3v1 和 ID3v2.2 到 ID3v2.4&#xff09;,协助开发者处理繁琐的文件操作相关&#xff0c;多用于操作文件场景的业务应用。 效果展示&#xff1a; 下载安装 ohpm install ohos/mp3agicOpenHarmony ohpm环境配…

MySQL的事务相关的语句的使用

MySQL的事务相关的语句的使用 事务是数据库管理系统执行过程中的一个程序单位&#xff0c;由一个或多个数据库操作组成。MySQL作为一款流行的关系型数据库管理系统&#xff0c;支持事务处理&#xff0c;允许用户定义一系列的操作&#xff0c;这些操作要么完全执行&#xff0c;…

西安大秦时代

西安大秦时代 大秦软件 公司简介 about us 西安大秦时代是技术型公司&#xff0c;技术领先是我们赖以生存的 基础&#xff01;服务是技术的延续&#xff0c;让客户满意&#xff0c;是我们服务的目 标&#xff0c;也是公司的生存之本&#xff01; 产品服务 西安大秦时代拥有…

【面试经典 150 | 数组】最后一个单词的长度

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;遍历 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回顾…

Hdu1068 Girls and Boys【二分图最大独立集】

Girls and Boys 题意 有 n n n 个学生&#xff0c;每个学生可能和若干个其他异性学生有过恋爱关系 现在要选择一些学生形成集合&#xff0c;使得集合内任意两个学生之间都没有过恋爱关系 思路 把学生抽象成点&#xff0c;恋爱关系抽象成边&#xff0c;题意即是求&#xff1…

ASP.NET基于WEB的选课系统

摘要 设计本系统的目的是对选课信息进行管理。学生选课系统维护模块主要完成的是系统管理与维护功能。课题研究过程中&#xff0c;首先对系统管理模块进行了详尽的需求分析&#xff0c;经分析得到系统管理模块主要完成如下的功能&#xff1a;用户基本信息、选课信息的录入,查看…

腾讯云优惠服务器购买攻略,想省钱,看这篇文章就够了

购买腾讯云服务器省钱攻略&#xff0c;先搞个腾讯云新用户身份&#xff0c;然后先领取云服务器优惠代金券&#xff0c;最后在腾讯云官方特价活动上下单购买。目前腾讯云服务器优惠价格61元一年、新老同享2核2G4M带宽99元一年、2核4G5M服务器165元一年、4核8G服务器646元15个月&…

基于Vue3的openlayers地图显示

基于Vue3的openlayers地图显示 &#xff08;1&#xff09;接着上一篇将讲&#xff0c;在components文件夹下创建BaseMap.vue文件夹 &#xff08;2&#xff09;在App.vue文件里面引入BaseMap.vue文件&#xff0c;如下代码所示&#xff1a; &#xff08;3&#xff09;在BaseMa…

upload-labs第十七十八关

第十七关 $is_upload false; $msg null;if(isset($_POST[submit])){$ext_arr array(jpg,png,gif);$file_name $_FILES[upload_file][name];$temp_file $_FILES[upload_file][tmp_name];$file_ext substr($file_name,strrpos($file_name,".")1);$upload_file …

上位机图像处理和嵌入式模块部署(树莓派4b进行驱动的编写)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 树莓派4b上面还支持驱动代码的编写&#xff0c;这是我没有想到的。这里驱动&#xff0c;更多的是一种框架的编写&#xff0c;不一定是编写真正的驱…

大珩PPT助手一键颜色设置

大珩PPT助手最新推出的一键设置文字颜色和背景色功能&#xff0c;为用户在创建演示文稿时带来了更便捷、高效的体验。这一功能使用户能够轻松调整演示文稿中文字的颜色和幻灯片的背景色&#xff0c;以满足不同场合和主题的需要。 以下是该功能的几个关键特点和优势&#xff1a…

opencv的cmake报错

opencv编译报错 CMakeDownloadLog.txt #use_cache "D:/opencv/.cache" #do_unpack "ippicv_2021.8_win_intel64_20230330_general.zip" "71e4f58de939f0348ec7fb58ffb17dbf" "https://raw.githubusercontent.com/opencv/opencv_3rdparty/1…

【Linux系统编程】第六弹---权限的概念

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、什么是权限 2、权限的本质 3、Linux中的用户 4、Linux中文件的权限 4.1、文件访问者的分类(角色) 4.2、文件类型和访问权…

书生浦语训练营第2期-第4节笔记

一、为什么要微调&#xff1f; 1. 适应特定任务或领域&#xff1a;虽然预训练的模型通常具有广泛的知识和理解能力&#xff0c;但它们可能不完全适应特定任务的需求。通过在特定的数据集上微调模型&#xff0c;可以使模型更好地理解和处理与特定任务或领域相关的数据。 2. 提高…

氮气柜是如何进行温度、湿度和氧含量控制的?

氮气柜的温湿度控制标准并不统一&#xff0c;具体设定值主要取决于所存储物料的特性与存储要求。 氮气柜的温度一般不直接控制&#xff0c;而是显示并反映柜内当前的环境温度&#xff0c;因为氮气柜的设计重点在于除湿而非降温。在某些高端应用场合&#xff0c;尤其是精密电子元…

软件杯 深度学习实现语义分割算法系统 - 机器视觉

文章目录 1 前言2 概念介绍2.1 什么是图像语义分割 3 条件随机场的深度学习模型3\. 1 多尺度特征融合 4 语义分割开发过程4.1 建立4.2 下载CamVid数据集4.3 加载CamVid图像4.4 加载CamVid像素标签图像 5 PyTorch 实现语义分割5.1 数据集准备5.2 训练基准模型5.3 损失函数5.4 归…

Spring Boot中JUnit 4与JUnit 5的如何共存

文章目录 前言一、先上答案二、稍微深入了解2.1 maven-surefire-plugin是什么2.2 JUnit4和JUnit5有什么区别2.2.1 不同的注解2.2.2 架构 前言 在maven项目中&#xff0c;生成单测时是否有这样的疑问&#xff1a;该选JUnit4还是JUnit5&#xff1f;在执行 mvn test 命令时有没有…