八股文-多线程、并发

八股文-多线程、并发

最近学到了一种方法,可以用于简历项目经验编写以及面试题目的回答

STAR法则:在什么背景下,你需要解决什么问题,你做了啥,得到了什么结果
情境(Situation): 描述你面对的特定情境或背景。
任务(Task): 说明你面临的具体任务或挑战。
行动(Action): 阐述你采取了什么行动来解决问题或完成任务。
结果(Result): 指出你的行动带来了什么结果,以及你取得了什么成就。
参考:https://blog.csdn.net/qq_37037348/article/details/139144523

多线程是啥?为啥要有多线程?

在单个程序中可以同时运行多个线程执行不同的任务。学习了一个操作系统上面运行多个进程的方法,一个进程上面用多个线程管理。计算机最早出现的时候还没有操作系统,程序直接运行在计算机上,这样一个计算机的功能有限,资源利用率也不高。所以就出现了操作系统,通过进程的方式实现一个计算机可以同时运行多个程序,同时一个程序里面又需要处理多种任务,如果所以任务用一个线程来执行,那么多个任务只能排队处理,同样效率低下,无法好好的利用资源(内存、磁盘IO、CPU等)。
并行处理、充分利用资源 → 提高性能和效率、改善用户体验

使用多线程带来的问题?

线程安全问题(一致性问题)、死锁(相互等待)、资源争抢(CPU时间、内存、I/O)、编程复杂、可见性(内存分为工作内存和主内存,这样做主要是为了提高效率)、有序性问题(指令重排)

怎么解决这些问题?

同步机制(volatile、synchronized、原子类、Lock显式锁)

指令重排是什么?为啥要指令重排?

编译器或者处理器对指令执行顺序进行调整,为了提高执行效率。对于重排的指令会遵循以下原则:不影响单线程执行的语义。但是多线程就不能够保证了(会出现可见性问题、有序性问题)。多线程下正常执行语句也不能够保证原子性,所以基于这两种场景,为了保证并发安全性,就出现了锁和其他的一些机制。主要包括volatile,synchronized,显式锁,原子类等

解决指令重排的方法:
Java提供了一些机制来解决指令重排带来的问题:

volatile关键字:通过使用volatile关键字,可以确保变量的读写操作对所有线程都是可见的,并且保证操作的有序性。volatile变量的写操作对任意后续的volatile变量的读操作都是可见的。(内存屏障阻止重排序,https://juejin.cn/post/6901283327160877063)

synchronized关键字:使用synchronized可以确保同一时间只有一个线程可以执行同步代码块,从而保证操作的原子性和有序性。

final关键字:对于final字段,一旦初始化完成,其值就不会被改变。这可以确保在构造函数中对final字段的赋值在构造函数结束后对其他线程是可见的。

原子类:Java提供了一系列的原子类(如AtomicInteger),这些类利用CAS(Compare-And-Swap)操作来保证操作的原子性,从而避免指令重排的问题。

指令重排为啥能够提高执行效率?

这个就是编译器和处理器做的一些优化,主要原则是提高各个硬件(CPU、内存、寄存器)的利用率,减少空闲时间

volatile是啥?有什么用?

这个就得说到JMM,Java内存模型(Java Memory Model,简称JMM)。内存模型把内存分为线程工作内存和主内存。加了volatile修饰的变量就会直接利用本地内存,这样多个线程set操作会直接从线程内存同步到主内存,get操作会直接从主内存同步到线程内存。
JMM的三个核心特性包括:

可见性:确保一个线程对共享变量的修改能够及时地被其他线程观察到。例如,使用volatile关键字修饰的变量,可以保证对该变量的读写操作对所有线程都是即时可见的。

原子性:确保操作是不可分割的,即当一个线程执行原子操作时,其他线程不能插入执行其他操作。Java中的原子操作包括对基本数据类型的赋值操作,以及synchronized块或方法。

有序性:JMM通过happens-before关系来确保操作的有序性。如果一个操作A happens-before 操作B,那么在执行操作B之前,操作A的结果已经对操作B可见,且操作A的执行顺序在操作B之前。

指令重排序破坏了可见性和有序性。
参考:https://www.jianshu.com/p/a67dc1c11088
双层校验锁:https://www.jianshu.com/p/c6a42c543abf

线程的生命周期

https://www.jianshu.com/p/c22ff5cc4a8f
在这里插入图片描述

synchronized底层实现?锁升级?

https://blog.csdn.net/qq_32907195/article/details/108906260
https://blog.csdn.net/m0_69519887/article/details/138546440
https://xiaolincoding.com/interview/juc.html#synchronized%E5%92%8Creentrantlock%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF
https://blog.csdn.net/zhouzhenghu123/article/details/140086311
https://cloud.tencent.com/developer/article/1911691
利用对象实现锁,每个对象都有一个相关联的监视器(monitor),监视器有4个重要的变量,计数器、当前线程,waitSet和entryList。
在这里插入图片描述

在这里插入图片描述
JDK 1.6 之前,synchronized 是重量级锁。JDK 1.6 之前,synchronized 是重量级锁,为了优化,就有了锁升级
在这里插入图片描述
处理锁升级还有其他优化手段,锁消除、锁粗化、锁自旋。
synchronized 核心优化方案主要包含以下 4 个:

锁膨胀:synchronized 从无锁升级到偏向锁,再到轻量级锁,最后到重量级锁的过程,它叫做锁膨胀也叫做锁升级。JDK 1.6 之前,synchronized 是重量级锁,也就是说 synchronized 在释放和获取锁时都会从用户态转换成内核态,而转换的效率是比较低的。但有了锁膨胀机制之后,synchronized 的状态就多了无锁、偏向锁以及轻量级锁了,这时候在进行并发操作时,大部分的场景都不需要用户态到内核态的转换了,这样就大幅的提升了 synchronized 的性能

锁消除:指的是在某些情况下,JVM 虚拟机如果检测不到某段代码被共享和竞争的可能性,就会将这段代码所属的同步锁消除掉,从而到底提高程序性能的目的。(比如单线程使用某些线程安全的容器,有可能不会加锁;实现是JIT 即时编译时,通过对运行上下文的扫描,经过逃逸分析,去除不可能存在共享资源竞争的锁,通过这种方式消除没有必要的锁,可以节省毫无意义的请求锁时间)

锁粗化:将多个连续的加锁、解锁操作连接在一起,扩展成一个范围更大的锁。(加锁解锁也需要消耗资源)

自适应自旋锁:指通过自身循环,尝试获取锁的一种方式,优点在于它避免一些线程的挂起和恢复操作,因为挂起线程和恢复线程都需要从用户态转入内核态,这个过程是比较慢的,所以通过自旋的方式可以一定程度上避免线程挂起和恢复所造成的性能开销。

内核态和用户态

https://www.jianshu.com/p/011f4062d372
用户态和内核态是程序运行的两种状态,
线程调度部分操作底层也会依赖操作系统,比如重量级锁,会依赖操作系统的。这个时候就相当于从用户态切换到内核态,然后获取到锁,又会切回来,这个过程是耗时操作。轻量级锁都是在用户态直接完成,不用惊动操作系统,是一种优化手段。
JVM对于os kernel来说呢就相当于是一个普通的应用程序,那么你想申请一把锁,对线程进行调度。实现这件事的时候需要向操作系统内核申请,操作系统内核帮你管理这些线程,管理好了之后反馈给你。这个过程简单来说就是 从用户态到内核态的访问,访问完了由内核态再反馈回来,这个就叫重量级锁。

逃逸分析

https://blog.csdn.net/sky15256567734/article/details/106786870
逃逸分析(Escape Analysis)是编译器优化技术中的一种,它用于分析对象的作用域,判断对象是否在方法中创建后,被外部方法所引用或者作为参数传递到其他方法中。基于这种分析,编译器可以进行一些优化,比如:

栈上分配:如果一个对象不会逃逸到方法之外,那么编译器可以将这个对象的内存分配从堆内存转移到栈内存。由于栈内存的分配和回收速度通常比堆内存快,这样可以提高程序的运行效率。

同步省略:如果一个对象不会被其他线程访问,即不会逃逸到线程之外,那么编译器可以省略对这个对象的同步操作,从而提高性能。

标量替换:对于不会逃逸的对象,如果其内部状态不需要封装在对象中,编译器可以将其替换为基本类型的集合,即标量。这样可以减少内存分配和提高缓存的局部性。

死代码消除:如果分析出某些代码路径不会执行,编译器可以将其优化掉。

在Java中,逃逸分析对于实现即时编译器(JIT)中的优化至关重要,尤其是在运行时编译的环境下,如HotSpot虚拟机。通过逃逸分析,JIT编译器能够在运行时决定是否可以应用上述优化。

需要注意的是,逃逸分析并不是在所有的场景下都能带来性能提升,有时候过度优化可能会导致代码膨胀,甚至因为优化错误而引入bug。因此,编译器在进行逃逸分析时需要权衡优化的收益和风险。

synchronized 和 lock的区别

可中断锁

https://blog.csdn.net/m0_50116974/article/details/140164578

怎么使用多线程?

继承Thread、实现Runnable接口、实现Callable接口(可以根据FutureTask拿到返回结果)、线程池
参考:
https://zhuanlan.zhihu.com/p/334737925
https://www.cnblogs.com/java1024/p/11950129.html
https://blog.csdn.net/weixin_44797490/article/details/91006241

线程池怎么用?原理?执行流程是咋样的?

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

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

相关文章

无人机维修保养一对一教学技术详解

随着无人机技术的日益普及和应用的广泛深入,无人机的维修保养成为确保飞行安全、延长使用寿命的关键环节。为了培养专业的无人机维护人才,一对一教学成为了一种高效、针对性的培训方式。以下将详细解析无人机维修保养一对一教学的技术要点,涵…

QT Layout布局,隐藏其中的某些部件后,不影响原来的布局

最近在工作时,被要求,需要将布局中的某些部件隐藏后,但不能影响原来的布局。 现在记录解决方案! 一、水平布局(垂直布局一样) ui中的布局 效果: 按钮可以任意隐藏,都不影响其中布…

Ceph 基本架构(一)

Ceph架构图 Ceph整体组成 Ceph 是一个开源的分布式存储系统,设计用于提供优秀的性能、可靠性和可扩展性。Ceph 的架构主要由几个核心组件构成,每个组件都有特定的功能,共同协作以实现高可用性和数据的一致性。 以下是 Ceph 的整体架构及其…

Pikachu靶场之XSS

先来点鸡汤,少就是多,慢就是快。 环境搭建 攻击机kali 192.168.146.140 靶机win7 192.168.146.161 下载zip,pikachu - GitCode 把下载好的pikachu-master,拖进win7,用phpstudy打开网站根目录,.....再用…

CleanMyMac 5 for Mac 最新中文破解版下载 系统优化垃圾清理工具

今天给大家带来的是CleanMyMac最新款CleanMyMac 5,它是一个全面的Mac清理和维护工具,通过提供多项强大的功能,帮助用户简化日常维护任务,提升系统性能,同时保护个人隐私和安全。无论是新手还是经验丰富的Mac用户&#…

京东广告投放平台整洁架构演进之路

作者:广告研发 赵嘉铎 前言 从去年开始京东广告投放系统做了一次以领域驱动设计为思想内核的架构升级,在深入理解DDD思想的同时,我们基于广告投放业务的本质特征大胆地融入了自己的理解和改造。新架构是从设计思想到落地框架都进行了彻底的…

Python 解析 Charles JSON Session File (.chlsj)

Charles 代理,是一款抓包软件,可以帮助我们抓取浏览器请求跟响应。 1、在 Filter 里面输入需要抓包的网址 2、右键 Export Session 3、文件类型选择 JSON Session File (.chlsj) 保存 4、解析响应的数据结构 response.body.text 是文本字符串。 # 导入…

自然语言处理-基于注意力机制的文本匹配

背景: 任务三:基于注意力机制的文本匹配 输入两个句子判断,判断它们之间的关系。参考ESIM(可以只用LSTM,忽略Tree-LSTM),用双向的注意力机制实现。 参考 《神经网络与深度学习》 第7章 Reaso…

SpringCloud微服务消息驱动的实践指南

Spring Cloud是一个用于构建分布式系统的开发工具,通过它可以快速搭建基于微服务架构的应用,并提供了丰富的功能和解决方案。在Spring Cloud中,消息驱动是一种常见的通信模式,通过消息传递来实现不同微服务之间的数据交互。本文将…

【移动端开发】“明日头条APP”

文章目录 1 系统概述1.1研究背景1.2研究意义 2 系统设计2.1 关键技术2.2 系统设计2.2.1 系统功能模块2.2.2 数据库设计 3 系统实现3.1 数据模型3.1.1 NewsURL3.1.2 NewsType3.1.3 NewsInfo 3.2 数据库操作3.2.1 DBOpenHelper3.2.2 DBManager 3.3 适配器类3.3.1 AddItem3.3.2 In…

LabVIEW机械产品几何精度质检系统

随着制造业的发展,对产品质量的要求越来越高,机械产品的几何精度成为衡量其品质的重要指标。为了提高检测效率和精度,开发了一套基于LabVIEW的几何精度质检系统,该系统不仅可以自动化地进行几何尺寸的测量,而且能实时分…

Qt 边框border - qss样式

border属性 实际上,border并不是一个单独的属性,在Qt样式表中,它通常指的是一系列与边框相关的属性的组合。然而,你也可以在一条样式规则中一次性设置所有这些值,如下所示: QPushButton { border: 2px sol…

smardaten无代码这么牛逼?逻辑编排不用代码!

目录 前言 经典案例 ①计划编排:数据操作自动化 ②工单派工:流程变更自动化 smardaten能力解析 一、逻辑控制篇 (1)变量定义与操作 (2)数据校验与反馈 (3)动态数据获取与回填…

演示:基于WPF自绘的中国省份、城市、区县矢量地图

一、目的:演示一个基于WPF自绘的中国省份、城市、区县矢量地图 二、效果 国 省 市 三、功能 支持实际经纬度显示 支持平移,缩放等功能 显示中国地图 显示各个省份地图 显示各个省份地图(包含在表格中,包含缩率图) 显…

Android Studio报错: Could not find pub.devrel:easypermissions:0.3.0, 改用linux编译

在Android studio中去编译开源的仓库,大概率就是各种编译不过,一堆错误,一顿改错,基本上会耗费非常多时间,比如: 这个就是改gradle版本,改成7.2 ,修改完成之后,还有其他报…

rabbitmq容器化部署

目录 需求 容器化部署rabbitmq服务 部署服务 验证及访问服务 rabbitmq配置LTS 服务验证 rabbitmq配置集群 部署集群 1、创建一个存放配置文件的目录 2、创建配置文件 3、部署各个节点 集群验证 需求 容器化部署rabbitmq服务 基础版本 系统ubuntu 24,docke…

Java后端框架---Spring

目录 一.Spring是什么? 二.Spring Hello World 搭建 三.XML配置bean管理 1.bean标签 2.依赖注入 3.依赖注入的补充 四.注解配置bean管理 1.开启注解扫描 2.使用注解对类进行配置 3.自动注入 五.面向切面编程AOP 1.概述 2.通知 六.spring事务管理 1.数据库…

【踩坑】装了显卡,如何让显示器从主板和显卡HDMI都输出

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 背景介绍 装了显卡后,开机默认是从显卡的HDMI输出,但这很不方便。如何让视频仍然从主板输出?或者说让显卡HDMI和主板…

系统 IO

"裸奔"层次:不带操作系统的编程 APP(应用程序) -------------------------------- Hardware(硬件) 特点:简单,应用程序直接操作硬件(寄存器) 缺点: 1. 搞应用开发的必须要了解硬件的实现细节,能够看懂原理图…

LeetCode_sql_day24(1212.查询球队积分)

描述 表: Teams ------------------------- | Column Name | Type | ------------------------- | team_id | int | | team_name | varchar | ------------------------- team_id 是该表具有唯一值的列。 表中的每一行都代表一支独立足球队。表: Matches…