多线程相关面试题(2024大厂高频面试题系列)

1、聊一下并行和并发有什么区别?
并发是同一时间应对多件事情的能力,多个线程轮流使用一个或多个CPU
并行是同一时间动手做多件事情的能力,4核CPU同时执行4个线程

2、说一下线程和进程的区别?
进程是正在运行程序的实例,进程中包含了线程,每个线程执行不同的任务
不同的进程使用不同的内存空间,在当前进程下的所有线程可以共享内存空间

3、如果在java中创建线程有哪些方式?

在java中一共有四种常见的创建方式,分别是:继承Thread类、实现
runnable接口、实现Callable接口、线程池创建线程。通常情况下,项目
中都会采用线程池的方式创建线程。

4、runnable 和 callable 两个接口创建线程有什么不
同呢?

Runnable 接口run方法无返回值;Callable接口call方法有返回值,是个泛
型,和Future、FutureTask配合可以用来获取异步执行的结果,调用FutureTask.get()得到可以得到返回值,此方法会阻塞主进程的继续
往下执行,如果不调用不会阻塞。

5、线程包括哪些状态,状态之间是如何变化的?

在JDK中的Thread类中的枚举State里面定义了6中线程的状态分别是:新
建、可运行、终结、阻塞、等待和有时限等待六种。
在这里插入图片描述
6、线程中的 wait 和 sleep方法有什么不同呢?
第一:方法归属不同
sleep(long) 是 Thread 的静态方法。而 wait(),是 Object 的成员方法,每个对象都有
第二:线程醒来时机不同
线程执行 sleep(long) 会在等待相应毫秒后醒来,而 wait() 需要被 notify 唤醒,wait() 如果不唤醒就一直等下去
第三:锁特性不同
wait 方法的调用必须先获取 wait 对象的锁,而 sleep 则无此限制
wait 方法执行后会释放对象锁,允许其它线程获得该对象锁(相当于我放弃cpu,但你们还可以用)而 sleep 如果在 synchronized 代码块中执行,并不会释放对象锁(相当于我放弃 cpu,你们也用不了)

7、如何停止一个正在运行的线程呢?

第一:可以使用退出标志,使线程正常退出,也就是当run方法完成后线程终止,一般我们加一个标记 这个标记得用volitale变量修饰
第二:可以使用线程的stop方法强行终止,不过一般不推荐,这个方法已作废
第三:可以使用线程的interrupt方法中断线程,内部其实也是使用中断标志来中断线程

8、讲一下synchronized关键字的底层原理?
synchronized 底层使用的JVM级别中的Monitor 来决定当前线程是否获得了锁,如果某一个线程获得了锁,在没有释放锁之前,其他线程是不能或得到锁的。synchronized 属于悲观锁。synchronized 因为需要依赖于JVM级别的Monitor ,相对性能也比较低。

9、能具体说下Monitor 吗?
monitor对象存在于每个Java对象的对象头中,synchronized 锁便是通过这种方式获取锁的,也是为什么Java中任意对象可以作为锁的原因monitor内部维护了三个变量:
WaitSet:保存处于Waiting状态的线程
EntryList:保存处于Blocked状态的线程
Owner:持有锁的线程
只有一个线程获取到的标志就是在monitor中设置成功了Owner,一个
monitor中只能有一个Owner在上锁的过程中,如果有其他线程也来抢锁,则进入EntryList 进行阻塞,当获得锁的线程执行完了,释放了锁,就会唤醒EntryList 中等待的线程竞争锁,竞争的时候是非公平的。

10、关于synchronized 的锁升级的情况了解吗?
Java中的synchronized有偏向锁、轻量级锁、重量级锁三种形式,分别对应了锁只被一个线程持有、不同线程交替持有锁、多线程竞争锁三种情况。

重量级锁:底层使用的Monitor实现,里面涉及到了用户态和内核态的切
换、进程的上下文切换,成本较高,性能比较低。

轻量级锁:线程加锁的时间是错开的(也就是没有竞争),可以使用轻量级锁来优化。轻量级修改了对象头的锁标志,相对重量级锁性能提升很多。每次修改都是CAS操作,保证原子性

偏向锁:一段很长的时间内都只被一个线程使用锁,可以使用了偏向锁,在第一次获得锁时,会有一个CAS操作,之后该线程再获取锁,只需要判断mark word中是否是自己的线程id即可,而不是开销相对较大的CAS命令一旦锁发生了竞争,都会升级为重量级锁

11、在高并发情况下,该如何控制使用锁呢?
可以采用ReentrantLock来加锁。

ReentrantLock是一个可重入锁:,调用 lock 方 法获取了锁之后,再次调用lock,是不会再阻塞,内部直接增加重入次数 就行了,标识这个线程已经重复获取一把锁而不需要等待锁的释放。

ReentrantLock是属于juc报下的类,属于api层面的锁,跟synchronized一样,都是悲观锁。通过lock()用来获取锁,unlock()释放锁。它的底层实现原理主要利用CAS+AQS队列来实现。它支持公平锁和非公平锁,两者的实现类似构造方法接受一个可选的公平参数(默认非公平锁),当设置为true时,表示公平锁,否则为非公平锁。公平锁的效率往往没有非公平锁的效率高。

12、CAS和AQS,你能介绍一下吗?
CAS的全称是: Compare And Swap(比较再交换);它体现的一种乐观锁的思想,在无锁状态下保证线程操作数据的原子性。

CAS使用到的地方很多:AQS框架、AtomicXXX类
在操作共享变量的时候使用的自旋锁,效率上更高一些CAS的底层是调用的Unsafe类中的方法,都是操作系统提供的,其他语言实现

AQS的话,其实就一个jdk提供的类AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架。内部有一个属性 state 属性来表示资源的状态,默认state等于0,表示没有获取锁,state等于1的时候才标明获取到了锁。通过cas 机制设置 state 状态在它的内部还提供了基于 FIFO 的等待队列,是一个双向列表,其中tail 指向队列最后一个元素,head 指向队列中最久的一个元素。

13、synchronized和Lock有什么区别 ?
第一,语法层面

synchronized 是关键字,源码在 jvm 中,用 c++ 语言实现,退出同步代码块锁会自动释放

Lock 是接口,源码由 jdk 提供,用 java 语言实现,需要手动调用 unlock 方法释放锁

第二,功能层面
二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能Lock 提供了许多 synchronized 不具备的功能,例如获取等待状态、公平锁、可打断、可超时、多条件变量,同时Lock 可以实现不同的场景,如ReentrantLock,ReentrantReadWriteLock

第三,性能层面
在没有竞争时,synchronized 做了很多优化,如偏向锁、轻量级锁,性能不赖在竞争激烈时,Lock 的实现通常会提供更好的性能统合来看,需要根据不同的场景来选择不同的锁的使用。

14、死锁产生的条件是什么?
t1 线程获得A对象锁,接下来想获取B对象的锁
t2 线程获得B对象锁,接下来想获取A对象的锁
这个时候t1线程和t2线程都在互相等待对方的锁,就产生了死锁

15、如何进行死锁诊断?
先通过jps来查看当前java程序运行的进程id

然后通过jstack来查看这个进程id,就能展示出来死锁的问题,并且,可以定位代码的具体行号范围,我们再去找到对应的代码进行排查就行了。

16、谈谈你对 volatile 的理解
volatile 是一个关键字,可以修饰类的成员变量、类的静态成员变量,主要有两个功能

第一:保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的,volatile关键字会强制将修改的值立即写入主存。

第二: 禁止进行指令重排序,可以保证代码执行有序性。底层实现原理是,添加了一个内存屏障,通过插入内存屏障禁止在内存屏障前后的指令执行重排序优化

17、线程池的种类有哪些?
在jdk中默认提供了4中方式创建线程池
第一个是:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回 收空闲线程,若无可回收,则新建线程。

第二个是:newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列 中等待。

第三个是:newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

第四个是:newSingleThreadExecutor 创建一个单线程化的线程池,它只会
用唯一的工作线程来执行任 务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

18、线程池的核心参数有哪些?
在线程池中一共有7个核心参数:

  1. corePoolSize 核心线程数目 - 池中会保留的最多线程数
  2. maximumPoolSize 最大线程数目 - 核心线程+救急线程的最大数目
  3. keepAliveTime 生存时间 - 救急线程的生存时间,生存时间内没有新任务,此线程资源会释放
  4. unit 时间单位 - 救急线程的生存时间单位,如秒、毫秒等
  5. workQueue - 当没有空闲核心线程时,新来任务会加入到此队列排队,队列满会创建救急线程执行任务
  6. threadFactory 线程工厂 - 可以定制线程对象的创建,例如设置线程名字、是否是守护线程等
  7. handler 拒绝策略 - 当所有线程都在繁忙,workQueue 也放满时,会触发拒绝策略,在拒绝策略中又有4种拒绝策略,当线程数过多以后,第一种是抛异常、第二种是由调用者执行任务、第三是丢弃当前的任务,第四是丢弃最早排队任务。默认是直接抛异常。

19、如何确定核心线程池呢?
IO密集型任务:推荐:核心线程数大小设置为2N+1 (N为计算机的CPU核数)

CPU密集型任务:推荐:核心线程数大小设置为N+1 (N为计算机的CPU核数)

20、为什么不建议使用Executors创建线程池呢?
主要原因是如果使用Executors创建线程池的话,它允许的请求队列默认长度是Integer.MAX_VALUE,这样的话,有可能导致堆积大量的请求,从而导致OOM(内存溢出)。

21、如果控制某一个方法允许并发访问线程的数量?
在jdk中提供了一个Semaphore类(信号量),它提供了两个方法,semaphore.acquire() 请求信号量,可以限制线程的个数,是一个正数,如果信号量是-1,就代表已经用完了信号量,其他线程需要阻塞了
第二个方法是semaphore.release(),代表是释放一个信号量,此时信号量的个数+1

22、如何保证Java程序在多线程的情况下执行安全呢?
如果解决的话,jdk中也提供了很多的类帮助我们解决多线程安全的问题,比如:
JDK Atomic开头的原子类、synchronized、LOCK,可以解决原子性问题
synchronized、volatile、LOCK,可以解决可见性问题
Happens-Before 规则可以解决有序性问题

23、谈谈你对ThreadLocal的理解
ThreadLocal 主要功能有两个,第一个是可以实现资源对象的线程隔离,让每个线程各用各的资源对象,避免争用引发的线程安全问题,第二个是实现了线程内的资源共享

24、ThreadLocal的底层原理实现了解吗?
在ThreadLocal内部维护了一个一个 ThreadLocalMap 类型的成员变量,用来存储资源对象

当我们调用 set 方法,就是以 ThreadLocal 自己作为 key,资源对象作为value,放入当前线程的 ThreadLocalMap 集合中

当调用 get 方法,就是以 ThreadLocal 自己作为 key,到当前线程中查找关联的资源值

当调用 remove 方法,就是以 ThreadLocal 自己作为 key,移除当前线程关联的资源值

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】常见指令1(ls指令、pwd指令、cd指令、touch指令、mkdir指令、rmdir指令、man指令、cp指令、mv指令、cat指令)

目录 01.ls指令与ll指令 02.pwd指令 03.cd指令 04.touch指令 05.mkdir指令 06.rmdir指令&&rm指令 07.man指令 08.cp指令 09.mv指令 10.cat指令 01.ls指令与ll指令 ls指令: 原型:list directory contents 语法:ls[选项][目录…

于建筑外窗遮阳系数测试的太阳光模拟器模拟太阳光照射房屋视频

太阳光模拟器是一种用于测试建筑外窗遮阳系数的高科技设备。它能够模拟太阳光照射房屋的情景,帮助建筑师和设计师更好地了解建筑外窗的遮阳性能,从而提高建筑的能源效率和舒适度。 这种模拟器的工作原理非常简单,它通过使用高亮度的光源和精密…

【音视频开发好书推荐】RTC程序设计:实时音视频权威指南

目录 1、WebRTC概述2、好书推荐3、本书内容4、本书特色5、作者简介6、谁适合看这本书 1、WebRTC概述 WebRTC(Web Real-Time Communication)是一个由Google发起的实时音视频通讯C开源库,其提供了音视频采集、编码、网络传输,解码显…

【python高级编程教程】笔记(python教程、python进阶)第三节:(1)多态与鸭子类型(Polymorphism and Duck Typing)

参考文章1:【比刷剧还爽】清华大佬耗时128小时讲完的Python高级教程!全套200集!学不会退出IT界! 参考文章2:清华教授大力打造的Python高级核心技术!整整100集,强烈建议学习(Python3…

集成算法(随机森林,AdaBoost,Xgboost,Stacking模型)

目录 一、前言 二、Bagging模型 三、Boosting模型 四、Stacking模型 五、总结 一、前言 集成算法(Enseamable learning) 集成算法一般考虑树模型,KNN就不太适合 目的:让机器学习效果更好,单个不好,一起…

【力扣白嫖日记】626.换座位

前言 练习sql语句,所有题目来自于力扣(https://leetcode.cn/problemset/database/)的免费数据库练习题。 今日题目: 626.换座位 表:Seat 列名类型idintstudentvarchar id 是该表的主键(唯一值&#xf…

Golang各版本的GC详解

go v1.3的标记清除法 清除的第一步:stw将可达对象标记删除未被标记对象 go v1.5三色标记法 从根节点出发,将下一个节点遍历为灰色,放入灰色集合中遍历灰色节点集合,把灰色能到达的节点标记为灰色,把自身标记为黑色&a…

UniSA: Unified Generative Framework for Sentiment Analysis

文章目录 UniSA:统一的情感分析生成框架文章信息研究目的研究内容研究方法1.总体架构图2.基准数据集SAEval3.Task-Specific Prompt4.Modal Mask Training5.Pre-training Tasks5.1Mask Context Modeling5.2Sentiment Polarity Prediction5.3Coarse-grained Label Con…

latex使用\rm将部分公式或者部分单词设置为正体

在LaTeX中,\rm 是用于设置文字为 “Roman” 字体的命令。这里的 “Roman” 字体通常指的是默认的文本字体,也就是没有特意设置为斜体或粗体的普通字体。然而,\rm 并不总是表示特定的字体样式,而是依赖于当前文档或环境的设置。 在…

TIA博途中安装和更新HSP硬件支持包的具体方法示例

TIA博途中安装和更新HSP硬件支持包的具体方法示例 下面介绍2种方法,大家可根据自己实际的情况来选择适合自己的方法。 方法1: 参考以下链接中的内容: 如何TIA博途中更新HSP硬件目录? 方法2:

力扣515. 在每个树行中找最大值(BFS,DFS)

Problem: 515. 在每个树行中找最大值 文章目录 题目描述思路复杂度Code 题目描述 思路 思路1:BFS 套用BFS模板,直接在遍历树的某一层时将当前层的最大值存入数组中 思路2:DFS 回溯思想,在递归时不断更新可选列表(根据…

(C语言)深入理解指针2之野指针与传值与传址与assert断言

(C语言)深入理解指针1基础:http://t.csdnimg.cn/iGA3V 前面我们了解了指针的一些基础知识,下面我们进行进一步的指针学习 目录 1. 野指针 6.1 野指针成因 1. 指针未初始化 2. 指针越界访问 3. 指针指向的空间释放 6.2 如何…

基于JavaWEB SpringBoot婚纱影楼摄影预约网站设计和实现

基于JavaWEB SSM SpringBoot婚纱影楼摄影预约网站设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言…

Git快速上手二

对Git命令的深入理解快速上手Git(包含提交至GitHub和Gitee)-CSDN博客 1.5 分支操作 1.5.1 分支原理 系统上线后,又要修改bug,又要开发新的功能。 由于新功能没有开发完,所以需要建立分支,一边修改bug,一边开发新功能,最终合并. 1.5.2 分支实操 创建…

每日一题 — 有效三角形的个数

611. 有效三角形的个数 - 力扣(LeetCode) 思路: 双指针思想,先将数据排序 然后先固定最大的数Max,也就是数组最后的数再定义一左一右两个下标 left 、 right,当这个值相加大于最大的数,那么他两…

【HTML】HTML基础7.2(有序列表)

目录 标签 效果 注意 标签 <ol> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> 。。。。。。 </ol> 效果 代码 <ol><li>银河护卫队 10000000000</li><l…

云计算的部署方式(公有云、私有云、混合云、社区云)

云计算的部署方式(公有云、私有云、混合云、社区云) 目录 零、00时光宝盒 一、云计算的部署方式 1.1、公有云&#xff08;Public Cloud&#xff09; 1.2、私有云&#xff08;Private Cloud&#xff09;  1.3、混合云&#xff08;Hybrid Cloud&#xff09; 1.4、社区云&am…

IO多路复用:2024/3/5

作业1、使用poll实现tcp服务器端&#xff0c;select实现tcp客户端 服务器端&#xff1a; #include <myhead.h> #define SER_IP "192.168.199.131" //服务端IP #define SER_PORT 8888 //服务端端口号int main(int argc, const char *argv[])…

调研图基础模型(Graph Foundation Models)

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 图基础模型&#xff08;Graph Foundation Models&#xff0c;简称 GFMs&#xff09; 是一种经过预训练的图大模型&#xff0c;旨在处理不同领域的图数据和任务。让我们详细探讨一下这个概念。 Github …

什么是MGR高可用(完整版)

MGR简介 MGR是MySQL Group Replication的缩写&#xff0c;即MySQL组复制。 在以往&#xff0c;我们一般是利用MySQL的主从复制或半同步复制来提供高可用解决方案&#xff0c;但这存在以下几个比较严重的问题&#xff1a; 主从复制间容易发生复制延迟&#xff0c;尤其是在5.6以前…