面试八股之线程篇2.7——线程中的并发锁篇——死锁与并发程序的问题

news2024/11/18 14:29:12

文章目录

      • 2.6 synchronized和Lock有什么区别 ?
      • 2.7 死锁产生的条件是什么?
      • 2.8 如何进行死锁诊断?
      • 2.10 ConcurrentHashMap
        • (1) JDK1.7中concurrentHashMap
        • (2) JDK1.8中concurrentHashMap
      • 2.11 导致并发程序出现问题的根本原因是什么
        • (1)原子性
        • (3)内存可见性
        • (3)有序性

2.6 synchronized和Lock有什么区别 ?

难易程度:☆☆☆☆

出现频率:☆☆☆☆

参考回答

  • 语法层面
    • synchronized 是关键字,源码在 jvm 中,用 c++ 语言实现
    • Lock 是接口,源码由 jdk 提供,用 java 语言实现
    • 使用 synchronized 时,退出同步代码块锁会自动释放,而使用 Lock 时,需要手动调用 unlock 方法释放锁
  • 功能层面
    • 二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能
    • Lock 提供了许多 synchronized 不具备的功能,例如获取等待状态、公平锁、可打断、可超时、多条件变量
    • Lock 有适合不同场景的实现,如 ReentrantLock, ReentrantReadWriteLock
  • 性能层面
    • 在没有竞争时,synchronized 做了很多优化,如偏向锁、轻量级锁,性能不赖
    • 在竞争激烈时,Lock 的实现通常会提供更好的性能

2.7 死锁产生的条件是什么?

难易程度:☆☆☆☆

出现频率:☆☆☆

死锁:一个线程需要同时获取多把锁,这时就容易发生死锁

例如:

t1 线程获得A对象锁,接下来想获取B对象的锁

t2 线程获得B对象锁,接下来想获取A对象的锁

代码如下:

package com.itheima.basic;

import static java.lang.Thread.sleep;

public class Deadlock {

    public static void main(String[] args) {
        Object A = new Object();
        Object B = new Object();
        Thread t1 = new Thread(() -> {
            synchronized (A) {
                System.out.println("lock A");
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (B) {
                    System.out.println("lock B");
                    System.out.println("操作...");
                }
            }
        }, "t1");

        Thread t2 = new Thread(() -> {
            synchronized (B) {
                System.out.println("lock B");
                try {
                    sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (A) {
                    System.out.println("lock A");
                    System.out.println("操作...");
                }
            }
        }, "t2");
        t1.start();
        t2.start();
    }
}

控制台输出结果

在这里插入图片描述

此时程序并没有结束,这种现象就是死锁现象…线程t1持有A的锁等待获取B锁,线程t2持有B的锁等待获取A的锁。

2.8 如何进行死锁诊断?

难易程度:☆☆☆

出现频率:☆☆☆

当程序出现了死锁现象,我们可以使用jdk自带的工具:jps和 jstack

步骤如下:

第一:查看运行的线程

在这里插入图片描述

第二:使用jstack查看线程运行的情况,下图是截图的关键信息

运行命令:jstack -l 46032

在这里插入图片描述

其他解决工具,可视化工具

  • jconsole

用于对jvm的内存,线程,类 的监控,是一个基于 jmx 的 GUI 性能监控工具

打开方式:java 安装目录 bin目录下 直接启动 jconsole.exe 就行

  • VisualVM:故障处理工具

能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的对象,反向查看分配的堆栈

打开方式:java 安装目录 bin目录下 直接启动 jvisualvm.exe就行

2.10 ConcurrentHashMap

难易程度:☆☆☆

出现频率:☆☆☆☆

ConcurrentHashMap 是一种线程安全的高效Map集合

底层数据结构:

  • JDK1.7底层采用分段的数组+链表实现

  • JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。

(1) JDK1.7中concurrentHashMap

数据结构

在这里插入图片描述

  • 提供了一个segment数组,在初始化ConcurrentHashMap 的时候可以指定数组的长度,默认是16,一旦初始化之后中间不可扩容
  • 在每个segment中都可以挂一个HashEntry数组,数组里面可以存储具体的元素,HashEntry数组是可以扩容的
  • 在HashEntry存储的数组中存储的元素,如果发生冲突,则可以挂单向链表

存储流程

在这里插入图片描述

  • 先去计算key的hash值,然后确定segment数组下标
  • 再通过hash值确定hashEntry数组中的下标存储数据
  • 在进行操作数据的之前,会先判断当前segment对应下标位置是否有线程进行操作,为了线程安全使用的是ReentrantLock进行加锁,如果获取锁是被会使用cas自旋锁进行尝试
(2) JDK1.8中concurrentHashMap

在JDK1.8中,放弃了Segment臃肿的设计,数据结构跟HashMap的数据结构是一样的:数组+红黑树+链表

采用 CAS + Synchronized来保证并发安全进行实现

  • CAS控制数组节点的添加

  • synchronized只锁定当前链表或红黑二叉树的首节点,只要hash不冲突,就不会产生并发的问题 , 效率得到提升

在这里插入图片描述

2.11 导致并发程序出现问题的根本原因是什么

难易程度:☆☆☆

出现频率:☆☆☆

Java并发编程三大特性

  • 原子性

  • 可见性

  • 有序性

(1)原子性

一个线程在CPU中操作不可暂停,也不可中断,要不执行完成,要不不执行

比如,如下代码能保证原子性吗?

在这里插入图片描述

以上代码会出现超卖或者是一张票卖给同一个人,执行并不是原子性的

解决方案:

1.synchronized:同步加锁

2.JUC里面的lock:加锁

在这里插入图片描述

(3)内存可见性

内存可见性:让一个线程对共享变量的修改对另一个线程可见

比如,以下代码不能保证内存可见性

在这里插入图片描述

解决方案:

  • synchronized

  • volatile(推荐)

  • LOCK

(3)有序性

指令重排:处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的

还是之前的例子,如下代码:

在这里插入图片描述

解决方案:

  • volatile

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

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

相关文章

SpringCloud(1)-Eureka相关配置

1.新建Module-注册中心 作为注册中心 1.1配置 pom.xml <!-- 引入 eureka-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency&g…

Little Snitch for Mac(小飞贼防火墙软件)v5.7.6注册激活版

Little Snitch for Mac&#xff0c;也被称为“小飞贼”防火墙软件&#xff0c;是一款专为Mac用户设计的网络安全工具。以下是关于Little Snitch for Mac的一些主要特点&#xff1a; Little Snitch for Mac(小飞贼防火墙软件)v5.7.6注册激活版下载 强大的监控能力&#xff1a;Li…

weblogic简介

WebLogic是美国Oracle公司出品的一个Application Server&#xff0c;它是一个基于JAVA EE架构的中间件。WebLogic主要用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器。它将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的…

论坛项目功能总结【Java面试项目】

论坛项目功能总结【Java面试项目】 前言推荐项目功能总结登录注册功能注册概述登录概述cookie-token实现redis实现配置 RedisUtilLoginControllerUserService测试redis做缓存 帖子 DiscussPostController发帖 addDiscussPost()查看帖子详情 getDiscussPost()置顶 setTop()加精 …

ESP32开发环境搭建Windows VSCode集成Espressif IDF插件开发环境搭建 IDF_V5.2.1

一、安装Visual Studio Code 下载地址&#xff1a;Download Visual Studio Code - Mac, Linux, Windows 打开上方链接&#xff0c;选择页面中的Windows版本&#xff0c;单击下载 将下载好的VSCodeUserSetup-x64-1.89.1.exe。单击右键&#xff0c;选择以管理员身份运行&#xf…

【Basic】BUU LFI COURSE

文章目录 前言一、BUU LFI COURSE二、知识点PHP的危险函数路径遍历攻击 解题感悟 前言 话不多说直接看题 一、BUU LFI COURSE emmm什么提示也没给啊&#xff0c;那只能点开看一看线索了 okok咱们先分析一下这段php代码 <?php /*** Created by PhpStorm.* User: jinzhao*…

R语言使用 ggscidca包优雅的绘制支持向量机决策曲线

DCA(Decision Curve Analysis)临床决策曲线是一种用于评价诊断模型诊断准确性的方法&#xff0c;在2006年由AndrewVickers博士创建&#xff0c;我们通常判断一个疾病喜欢使用ROC曲线的AUC值来判定模型的准确性&#xff0c;但ROC曲线通常是通过特异度和敏感度来评价&#xff0c;…

基于Nacos实现Sentinel规则持久化

基于Nacos实现Sentinel规则持久化 一、Sentinel使用痛点二、解决方案2.1 保存本地文件2.2 保存数据库2.3 保存到Nacos 三、规则持久化到Nacos3.1 Nacos服务端修改配置3.2 Sentinel控制台修改配置3.3 Nacos数据源整合到Sentinel中 一、Sentinel使用痛点 SpringCloudAlibaba帮我…

react 下拉框内容回显

需要实现效果如下 目前效果如下 思路 : 将下拉框选项的value和label一起存储到state中 , 初始化表单数据时 , 将faqType对应的label查找出来并设置到Form.Item中 , 最后修改useEffect 旧代码 //可以拿到faqType为0 但是却没有回显出下拉框的内容 我需要faqType为0 回显出下拉…

Laravel 11 PHP8

一直都是用laravel 7 左右的&#xff0c;现在要求将项目升级到laravel 11 和使用PHP8&#xff0c;随手记录一些小问题&#xff0c;laravel 11的包是领导给的&#xff0c;没有使用composer 安装&#xff0c;所以我也不确定和官方的是否一致 遇到这问题 可以这样 env 中默认的数…

基于Vue的验证码实现

一、验证码核心实现 创建slide-verify.vue&#xff0c;代码如下&#xff1a; <template><divclass"slide-verify":style"{ width: w px }"id"slideVerify"onselectstart"return false;"><!-- 图片加载遮蔽罩 -->&…

8操作系统定义、分类及功能+设备管理+作业管理 软设刷题 软考+

操作系统定义、分类及功能设备管理作业管理 知识点1-55-1010-1515-2020-2525-3030-35 刷题操作系统定义、分类及功能1-55-1010-15作业管理1-5设备管理1-55-10 知识点 1-5 1 嵌入式操作系统的特点&#xff1a; 1.微型化&#xff0c;从性能和成本角度考虑&#xff0c;希望占用的…

Android软件渲染流程

Android软件渲染流程 一.渲染流程1.VSync信号的监听2.VSync信号触发绘制 二.渲染原理1.画布的获取1.1 渲染缓存的初始化1.2 graphics::Canvas的创建1.3 graphics::Canvas与渲染缓存的绑定1.3.1 SkBitmap的初始化1.3.2 SkiaCanvas与SkBitmap的绑定1.3.3 SkCanvas的创建 2.矩形的…

【Day7:JAVA面向对象的初级使用】

目录 1、类和对象1.1 类的介绍1.2 类和对象的关系1.3 类的组成 2、对象内存图2.1 单个对象内存图2.2 两个对象内存图2.3 两个引用指向相同内存图 3、成员变量和局部变量3.1 成员变量和局部变量的区别 4、this关键字4.1 this可以解决的问题4.2 this介绍4.3 this内存图4.4 this总…

BOM..

区别&#xff1a;

验证码识别插件-captcha-killer

前言 想必大家都会使用burp进行爆破,当遇到带验证码的登录表单进行爆破时,基本尝试抓包后观察验证码是否主动更新,或者进行验证码绕过(我是十八期萌新,听风风说的有这个方法,但我还没学到),机缘巧合下我接触到了captcha-killer这个插件,可以提供给大家第三种爆破思路&#xff…

线程数据共享必学的3个工具类: ThreadLocal InheritableThreadLocal TransmittableThreadLocal

线程数据共享必学的3个工具类&#xff1a; ThreadLocal InheritableThreadLocal TransmittableThreadLocal 1.ThreadLocal:在当前线程中共享数据的&#xff0c;JUC 中提供的 2.InheritableThreadLocal:也是JUC中的一个工具类&#xff0c;解决 ThreadLocal 难以解决的问题 3.Tra…

MPLS原理与配置

1.MPLS概述 &#xff08;1&#xff09;传统IP路由转发 &#xff08;2&#xff09;MPLS基本概念 ⦁ MPLS起源于IPv4&#xff08;Internet Protocol version 4&#xff09;&#xff0c;其核心技术可扩展到多种网络协议&#xff0c;包括IPv6&#xff08;Internet Protocol ver…

WPF中CommandParameter用法

1. 界面样式 2. XAML中代码部分 <ButtonGrid.Row"0"Grid.Column"1"Command"{Binding BtnClick_Number}"CommandParameter"7"Content"7"Style"{StaticResource BtnStyle_Num}" /> <ButtonGrid.Row"…

我的第一个JAVA程序IDEA版

目录 第一步 新建一个空项目第二步 新建模块第三步 新建包第四步 新建类第五步 新建main方法 第一步 新建一个空项目 第二步 新建模块 第三步 新建包 第四步 新建类 然后在包文件夹下新建类 第五步 新建main方法