【Java】面试题 并发安全 (2)

文章目录

  • 可重入锁(ReentrantLock)知识总结
    • 1. 可重入锁概念与特点
    • 2. 基本语法与使用注意事项
    • 3. 底层实现原理
    • 4. 面试回答要点
  • synchronized与lock的区别
  • 死锁相关面试题讲解
  • 死锁产生的四个条件
  • ConcurrentHashMap
    • 2. JDK1.7的ConcurrentHashMap
      • 结构
      • 添加数据逻辑
      • 存在问题
    • 3. JDK1.8的ConcurrentHashMap
      • 结构优化
      • 保证线程安全方式
    • 4. 对比总结
      • 底层数据结构
      • 锁的方式
  • 导致并发程序出现问题的根本原因

可重入锁(ReentrantLock)知识总结

1. 可重入锁概念与特点

  • 概念:ReentrantLock是可重入锁,同一线程可多次获取该锁。
  • 特点
    • 可中断:与synchronized不同,ReentrantLock可在获取锁过程中被中断。
    • 可设置超时时间:获取锁时可设置超时时间,超时未获取到锁可放弃,避免无限等待。
    • 支持公平锁和非公平锁:默认是非公平锁,也可通过构造函数设置为公平锁。公平锁按等待顺序获取锁,非公平锁允许插队,提高性能但可能导致某些线程长时间等待。
    • 支持多个条件变量:类似synchronized中的wait/notify方法,可创建多个条件变量控制线程等待和唤醒,更灵活。

在这里插入图片描述

2. 基本语法与使用注意事项

  • 语法
    • 创建ReentrantLock对象。
    • 在try块中调用lock方法获取锁。
    • 在finally块中调用unlock方法释放锁,确保锁一定释放,避免死锁。
  • 注意事项:必须在finally块中释放锁,防止异常导致锁未释放引发死锁。

在这里插入图片描述

3. 底层实现原理

  • 基于AQS实现:ReentrantLock底层依赖AbstractQueuedSynchronizer(AQS)实现,AQS维护同步状态和线程等待队列。
  • 构造函数与锁类型
    • 无参构造函数默认创建非公平锁。
    • 带参数构造函数可传入特定参数创建公平锁或非公平锁。
  • 工作方式
    • 非公平锁获取锁:线程先尝试通过CAS操作修改同步状态state,成功则获取锁并设置当前线程为持有锁线程;失败则进入等待队列,但进入队列前仍会再次尝试获取锁(插队行为),若此时锁可用可直接获取。
    • 公平锁获取锁:线程先检查等待队列中是否有前驱节点,有则进入等待队列按先来先得顺序获取锁;无前驱节点则尝试通过CAS操作获取锁。
    • 锁释放:释放锁时唤醒等待队列中的线程重新竞争锁。

4. 面试回答要点

  • 强调ReentrantLock是可重入锁,同一线程可多次调用lock方法。
  • 提及底层主要使用CAS和AQS实现,重点解释AQS工作原理。
  • 说明ReentrantLock支持公平锁和非公平锁,无参构造函数默认是非公平锁,可传参设置公平锁。

在这里插入图片描述


文章目录

  • 可重入锁(ReentrantLock)知识总结
    • 1. 可重入锁概念与特点
    • 2. 基本语法与使用注意事项
    • 3. 底层实现原理
    • 4. 面试回答要点
  • synchronized与lock的区别
  • 死锁相关面试题讲解
  • 死锁产生的四个条件
  • ConcurrentHashMap
    • 2. JDK1.7的ConcurrentHashMap
      • 结构
      • 添加数据逻辑
      • 存在问题
    • 3. JDK1.8的ConcurrentHashMap
      • 结构优化
      • 保证线程安全方式
    • 4. 对比总结
      • 底层数据结构
      • 锁的方式
  • 导致并发程序出现问题的根本原因


synchronized与lock的区别

在这里插入图片描述

  1. 面试题引入
    • 题目:synchronized与lock有什么区别。
    • 回答思路:从语法、功能、性能三个层面回答,重点在功能层面。
  2. 语法层面区别
    • 实现方式:synchronized是关键字,由JVM提供,C++语言实现;lock由JDK提供,用Java语言实现。
    • 锁释放机制:使用synchronized时,退出同步块会自动释放锁;lock需调用unlock才能释放锁。
  3. 功能层面区别
    • 相同点:都属于悲观锁,具备互斥同步锁重入功能。
    • 不同点:lock提供更多功能,如公平锁、可打断、可超时、多条件变量等。
      • 公平锁:使用ReentrantLock时,可通过带条件的构造函数传true实现。
      • 可打断锁
        • 演示代码:创建t1线程,使用lock.Interruptibly()方法开启可打断锁,若被打断抛异常,否则正常进入锁并释放锁。
      • 可超时锁
        • 演示代码:线程获取锁调用tryLock方法,成功返回true,失败返回false,可设置超时时间,超时后放弃获取锁或获取成功执行业务。
      • 多条件变量
        • 演示代码:创建锁后可多次调用new Condition声明多个条件变量,线程可按条件等待
  4. 适合不同场景的实现及读写锁(功能层面)
    • ReentrantLock:与synchronized类似但功能更多。
    • 读写锁(ReentrantReadWriteLock):能支撑更高并发量,读操作可不加锁,写操作需加锁,适用于大量读需求的场景。
  5. 性能层面区别
    • 无竞争时:synchronized做了很多优化,如偏向锁、轻量级锁,性能还行。
    • 竞争激烈时:lock往往提供更好性能。

死锁相关面试题讲解

在这里插入图片描述

  1. 死锁产生条件及示例演示
    • 产生条件:一个线程同时获取多把锁时易发生死锁。
    • 示例代码分析:代码中有object aobject b两个对象,t1线程先获取a锁,在a锁代码块中再获取b锁;t2线程先获取b锁,在b锁代码块中再获取a锁,然后开启两个线程,程序会一直运行,出现死锁。
  2. JDK工具诊断死锁问题介绍
    • 死锁情况t1持有a锁等待b锁,t2持有b锁等待a锁,形成死锁。
    • 工具介绍:使用jdk提供的jpsjstack工具诊断死锁。jps可输出当前运行的所有进程状态信息,jstack可查看java进程内线程的堆栈信息。
    • 诊断步骤:先使用jps找到死锁代码的进程id(如24380),再使用jstack加进程id查看日志信息,日志最后会提示死锁,分析t1t2线程等待和锁住的锁,以及可能出现问题的代码行数,根据提示打开代码分析多把锁导致的死锁问题并修改。

在这里插入图片描述

  1. JDK可视化工具jconsole检查死锁
    • 工具介绍jdk自带可视化工具jconsole,可用于jvm的内存、线程、类的监控。
    • 检查步骤:打开jconsole,选择本地连接,找到要监控的进程(如24380),选择不安全链接,点击线程选项卡中的检查死锁,可看到t2t1线程发生死锁及相关日志,根据提示检查对应代码解决死锁问题。
  2. VisualVM检查死锁及总结
    • 检查流程:找到VisualVM(安装目录与jconsole相同),双击打开,在本地选择要检查的进程(如24380),切换到进程权限,会提示检查到死锁,点击线程dump获取更多信息,日志中可看到与jstack类似的t1t2线程等待和锁住锁的信息,根据提示的代码行号到附近查找问题。
    • 总结:死锁产生条件是一个线程同时获得多把锁。诊断方法可先使用jpsjstack,也可使用jconsoleVisualVM检查死锁问题,根据提示分析代码解决死锁。

死锁产生的四个条件

在这里插入图片描述

死锁是指在多道程序环境下,多个进程因竞争资源而造成的一种僵局,若无外力作用,这些进程都将无法向前推进。在操作系统中,死锁产生的条件有以下四个:

  1. 互斥条件:指进程对所分配到的资源进行排他性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其他进程请求该资源,则请求者只能等待,直至占有该资源的进程释放。
  2. 请求和保持条件:指进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
  3. 不可剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
  4. 环路等待条件:指在发生死锁时,必然存在一个进程-资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

这四个条件是死锁产生的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。在实际操作系统中,为了避免死锁的发生,通常会采用一些策略来破坏这些条件,例如资源分配策略、死锁检测与恢复机制等。


ConcurrentHashMap

Java 8的 ConcurrentHashMap 是线程安全的哈希表,有如下关键特性:

  • 数据结构:采用数组加链表加红黑树结构。初始为数组,链表长度达阈值(8)且桶数超64时,链表转红黑树,提升查找效率。
  • 并发控制:摒弃Java 7的分段锁,改用更细粒度的锁机制。使用 CAS 操作更新部分内容,对单个桶用 synchronized 同步,降低锁粒度,提升并发性能。
  • 常用方法put 用于插入键值对;get 根据键取值;compute 对指定键计算并更新或插入值;forEach 遍历键值对。
  • 适用场景:适用于高并发、读多写少场景,以及多线程环境下需线程安全哈希表的情况。

2. JDK1.7的ConcurrentHashMap

在这里插入图片描述

结构

  • 整体结构:采用分段的数组加链表实现。
  • Segment数组:不能扩容,每个下标对应另一个可扩容数组,该数组可挂链表或直接存储数据。

添加数据逻辑

  • 计算key哈希值定位Segment数组下标。
  • 找到下标后用ReentrantLock锁住该位置。
  • 再次通过哈希值定位哈希表数组位置存储数据。

存在问题

  • 性能低:多个key定位到同一Segment下标时,只有一个线程能操作。
  • 数组不能扩容:Segment数组长度在创建时确定。

3. JDK1.8的ConcurrentHashMap

在这里插入图片描述

结构优化

  • 放弃Segment数组,采用与HashMap相同结构,即数组加链表加红黑树。

保证线程安全方式

  • 添加新节点:通过CAS自旋操作保证数据安全。
  • 已有链表或红黑树:用synchronized锁住首节点,锁力度更细,效率更高。

4. 对比总结

底层数据结构

  • 1.7:分段的数组加链表。
  • 1.8:数组加链表加红黑树。

锁的方式

  • 1.7:Segment数组的分段锁(ReentrantLock),锁住范围大。
  • 1.8:添加新节点用CAS,对链表或红黑树用synchronized锁首节点,性能更好。

导致并发程序出现问题的根本原因

  1. 并发编程三大特性
    • 原子性
      • 定义:线程在CPU中的操作不可暂停、中断,要么执行完成,要么不执行。
      • 抢票代码示例:有10张票,多线程抢票可能出现超卖或一张票卖给多人,证明代码非原子操作。
      • 解决方法:加锁(synchronized关键字、lock锁)使代码具有原子性。
    • 可见性
      • 定义:一个线程对共享变量修改后,要让另一个线程可见。
      • 代码示例:线程一循环取反共享变量flag,线程二将其改为true,但线程一可能读不到该修改,循环不退出。
      • 解决方法:加锁(性能不高)或在共享变量上使用volatile
    • 有序性
      • 指令重排概念:处理器为提高效率可能打乱代码顺序执行,可能导致问题。
      • 代码示例:对共享变量xy进行赋值和读取操作,若出现x = 1, y = 0的情况,可能是指令重排序。
      • 解决方法:在共享变量上添加volatile(最好在y上添加)禁止指令重排序。
  2. 总结
    • 回答导致并发程序出现问题的根本原因时,需提及并发编程的三大特性及解决方法。
    • 原子性用synclock锁解决;内存可见性推荐用volatile,也可用锁;有序性通过在共享变量上加volatile禁止指令重排序。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yolov3算法及其改进

yolov3算法及其改进 1、yolov3简介2、yolov3的改进2.1、backbone的改进2.1.1、darknet19相对于vgg16有更少的参数,同时具有更快的速度和更高的精度2.1.2、resnet101和darknet53,同样具有残差结构,精度也类似,但是darknet具有更高的…

python报错ModuleNotFoundError: No module named ‘visdom‘

在用虚拟环境跑深度学习代码时,新建的环境一般会缺少一些库,而一般解决的方法就是直接conda install,但是我在conda install visdom之后,安装是没有任何报错的,conda list里面也有visdom的信息,但是再运行代…

Jenkins 构建流水线

在 Linux 系统上安装 Jenkins 服务,以及配置自动化构建项目 前置准备环境:docker、docker-compose、jdk、maven 一、环境搭建 1. Jenkins 安装 (1)拉取镜像 # 安装镜像包,默认安装最新版本 docker pull jenkins/jen…

大数据技术-Hadoop(二)HDFS的介绍与使用

目录 1、HDFS简介 1.1 什么是HDFS 1.2 HDFS的优点 1.3、HDFS的架构 1.3.1、 NameNode 1.3.2、 NameNode的职责 1.3.3、DataNode 1.3.4、 DataNode的职责 1.3.5、Secondary NameNode 1.3.6、Secondary NameNode的职责 2、HDFS的工作原理 2.1、文件存储 2.2 、数据写…

vue3使用element-plus,解决 el-table 多选框,选中后翻页再回来选中失效问题

问题&#xff1a;勾选的数据分页再回来回消失 1.在el-table中加 :row-key"getRowKey" const getRowKey (row) > { return row.id; // id必须是唯一的 }; 2.给type为selection的el-table-column添加上reserve-selection属性 <el-tableref"multipleTab…

go语言的成神之路-筑基篇-gin常用功能

第一节-gin参数绑定 目录 第一节-?gin参数绑定 ShouldBind简要概述 功能&#xff1a; 使用场景&#xff1a; 可能的错误&#xff1a; 实例代码 效果展示 第二节-gin文件上传 选择要上传的文件 选择要上传的文件。 效果展示? 代码部分 第三节-gin请求重定向 第…

五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 光伏功率预测&#xff01;五模型对比&#xff01;Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测(Matlab2023b 多输入单输出) 1.程序已经调试好&#xff0c;替换数据集后&#xff0c;仅运…

12.27【net】【review】【day3】

第三章 l CSMA/CD ( Carrier Sense Multiple Access with Collision Detection) &#xff1a; 载波监听多点接入 / 碰撞 检测。 l 多点接入 &#xff1a; 说明这是总线型 网络。许多 计算机以多点接入的方式连接在一根总线上。 l 载波监听&#xff1a; 即“ 边发送边监听”。…

Python学生管理系统(MySQL)

上篇文章介绍的Python学生管理系统GUI有不少同学觉得不错来找博主要源码&#xff0c;也有同学提到老师要增加数据库管理数据的功能&#xff0c;本篇文章就来介绍下python操作数据库&#xff0c;同时也对上次分享的学生管理系统进行了改进了&#xff0c;增加了数据库&#xff0c…

实现类似gpt 打字效果

1. css的动画&#xff08;animation) css中实现动画有两种方式&#xff1a;transition过渡动画、 animation自定义动画。 具体的可以看MDN链接&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation 使用keyframes自定义关键帧动画并未其命名使用自定义动…

OpenHarmony-5.PM 子系统(2)

电池服务组件OpenHarmony-4.1-Release 1.电池服务组件 Battery Manager 提供了电池信息查询的接口&#xff0c;同时开发者也可以通过公共事件监听电池状态和充放电状态的变化。电池服务组件提供如下功能&#xff1a; 电池信息查询。充放电状态查询。关机充电。 电池服务组件架…

软考:系统架构设计师教材笔记(持续更新中)

教材中的知识点都会在。其实就是将教材中的废话删除&#xff0c;语言精练一下&#xff0c;内容比较多&#xff0c;没有标注重点 系统架构概述 定义 系统是指完成某一特定功能或一组功能所需要的组件集&#xff0c;而系统架构则是对所有组件的高层次结构表示&#xff0c;包括各…

反应力场的生成物、反应路径分析方法

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

HarmonyOS NEXT 实战之元服务:静态案例效果---妙语集语

背景&#xff1a; 前几篇学习了元服务&#xff0c;后面几期就让我们开发简单的元服务吧&#xff0c;里面丰富的内容大家自己加&#xff0c;本期案例 仅供参考 先上本期效果图 &#xff0c;里面图片自行替换 效果图1完整代码案例如下&#xff1a; import { authentication } …

C#WPF基础介绍/第一个WPF程序

什么是WPF WPF&#xff08;Windows Presentation Foundation&#xff09;是微软公司推出的一种用于创建窗口应用程序的界面框架。它是.NET Framework的一部分&#xff0c;提供了一套先进的用户界面设计工具和功能&#xff0c;可以实现丰富的图形、动画和多媒体效果。 WPF 使用…

【递归与回溯深度解析:经典题解精讲(下篇)】—— Leetcode

文章目录 有效的数独解数独单词搜索黄金矿工不同的路径||| 有效的数独 递归解法思路 将每个数独的格子视为一个任务&#xff0c;依次检查每个格子是否合法。 如果当前格子中的数字违反了数独规则&#xff08;在行、列或 33 小方块中重复&#xff09;&#xff0c;直接返回 Fals…

SpringCloudAlibaba实战入门之路由网关Gateway断言(十二)

上一节课中我们初步讲解了网关的基本概念、基本功能,并且带大家实战体验了一下网关的初步效果,这节课我们继续学习关于网关的一些更高级有用功能,比如本篇文章的断言。 一、网关主要组成部分 上图中是核心的流程图,最主要的就是Route、Predicates 和 Filters 作用于特定路…

进军AI大模型-环境配置

语言环境配置 合法上网工具&#xff1a; 这个T子试试&#xff0c;一直稳定。走我链接免费用5天: https://wibnm.com/s/ywtc01/pvijpzy python版本&#xff1a; python3.12 Langchain: Introduction | &#x1f99c;️&#x1f517; LangChain v0.3 9月16日升级的版本 pip3…

`we_chat_union_id IS NOT NULL` 和 `we_chat_union_id != ‘‘` 这两个条件之间的区别

文章目录 1、什么是空字符串&#xff1f;2、两个引号之间加上空格 好的&#xff0c;我们来详细解释一下 we_chat_union_id IS NOT NULL 和 we_chat_union_id ! 这两个条件之间的区别&#xff0c;以及它们在 SQL 查询中的作用&#xff1a; 1. we_chat_union_id IS NOT NULL 含…

elementUI——upload限制图片或者文件只能上传一个——公开版

最近在写后台管理系统时&#xff0c;遇到一个需求&#xff0c;就是上传图片&#xff0c;有且仅能上传一张。 效果图如下&#xff1a; 功能描述&#xff1a;上传图片时&#xff0c;仅支持单选&#xff0c;如果上传图片成功后&#xff0c;展示图片&#xff0c;并隐藏添加图片的…