Java面试题库——多线程

news2025/1/19 17:13:52

1.并行和并发有什么区别?

并行:是指两个或多个事件在同一时刻发生,是在不同实体上的多个事件;
并发:是指两个或多个事件在同一时间间隔发生,是同一实体上的多个事件。

2.线程和进程的区别?

根本区别:进程是资源分配的基本单位,线程是程序执行的基本单位。
资源开销:每个进程都有独立的代码和数据空间,程序之间的切换会有较大的开销;线程可以看作轻量级的进程,同一线程共享代码和数据空间,每个进程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
包含关系:如果一个进程中有多个线程,则执行过程不是一条线的,而是多条线共同完成的;线程是进程的一部分,所以线程也被称为轻量级进程。
内存分配:同一进程的线程共享本进程的地址和资源,而进程之间的地址空间是相互独立的。
影响关系:一个进程崩溃后,在保护模式下不会对其它进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
执行过程:每个独立的进程有程序运行的入口、顺序执行的序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行。

3.守护线程是什么?

在Java线程开发中有两种线程:User Thread(用户线程)、Daemon Thread(守护线程)。
普通用户线程在JVM退出时依然会继续执行,导致JVM并不能退出。
普通线程可以通过setDaemon(true)方法设置为守护线程,守护线程在JVM退出时会自动结束运行。
当JVM所有的非守护线程结束运行时,JVM会自动退出。

4.创建线程有哪几种方式?

(1)继承Thread类并实现run方法,调用继承类的start方法开启线程;
(2)实现Runnable接口,重写run方法,调用线程对象的start方法开启线程;
(3)实现Callable接口,实现call方法,并用FutureTask类包装Callable对象开启线程。

推荐使用Runnable接口,因为Java 中的继承是单继承,一个类有一个父类,如果继承了 Thread 类就无法再继承其他类了,显然使用 Runnable接口更为灵活

5.说一下 runnable 和 callable 有什么区别?

实现Callable接口的任务能够返回执行结果,而实现Runnable接口的任务线程并不能返回执行结果。
Callable接口的call方法允许抛出异常,而Runnable接口的run方法的异常只能在内部消化,不能继续上抛。

6.线程的基本状态以及状态之间的关系?

在这里插入图片描述

基本状态:新建、就绪、运行、阻塞、死亡
其中Running表示运行状态,Runnable表示就绪状态,Blocked表示阻塞状态,阻塞状态又分多种情况,可能是因为调用了wait()方法进入等待池,也可能是执行同步方法或同步代码块进入等锁池,或者是调用sleep()方法或jion()方法等待休眠或其它线程结束,或是因为发生了I/O中断。

7.sleep()和wait()有什么区别?

sleep的类是Thread,wait的类是Object
sleep后程序不会释放同步锁,wait后程序会释放同步锁
sleep可以指定睡眠时间,自动唤醒,wait可以直接用notify唤醒

8.线程的 sleep()方法和 yield()方法有什么区别?

(1)sleep()方法给其它线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
(2)线程执行 sleep()方法后转入阻塞(blocked)状态,而执行 yield()方法后转入就绪(ready)状态;
(3)sleep()方法声明抛出 InterruptedException,而 yield()方法没有声明任何异常;
(4)sleep()方法比 yield()方法(跟操作系统 CPU 调度相关)具有更好的可移植性。

9.notify()和notifyAll()有什么区别?

notify()方法会唤醒对象等待池中的一个线程,进入锁池;
notifyAll()方法会唤醒对象等待池中的所有线程,进入锁池。

10.线程中的run()和start()有什么区别?

调用start()方法是用来启动线程,轮到该线程执行时,会自动调用run方法;
直接运行run方法无法达到启动多线程的目的,相当于调用Thread对象的run方法;
一个线程的start方法只能调用一次,多次调用会抛出异常;而run方法可以调用多次。

11.什么是线程池?

在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在 Java 中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这就是”池化资源”技术产生的原因。
线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。

12.创建线程池有哪几种方式?

主要使用Excutors提供的通用线程池创建方法,去创建不同配置的线程池。
newCachedThreadPool():用来处理大量短时间工作任务的线程池;
newFixedThreadPool(int nThread):重用指定数目的线程;
newSingleThreadExecutor():工作线程数目限制为1;
newSingleThreadScheduledExecutor()和newScheduledThreadPoll(int corePollSize):可以进行周期或定时性的工作调度;
newWorkStealingPool(int parallelism):JDK8以后才加入。

13.线程池有哪些状态?

RUNNING:线程池被创建,可以接收新线程;
SHUTDOEWN:线程池被关闭,不接收新线程,但是可以处理已有的线程。
STOP:线程池停止,不接受新线程,中断当前的线程,并且不会处理已有的线程。
TIDYING:线程池等待,当线程池处于SHUTDOWN或STOP状态,并且任务队列为空且执行中任务为空则会转变;
TERMINATED:线程池彻底终止,线程池在TIDYING状态中执行完terminated()方法后就会转变为此状态。

14.线程池中submit()和execute()方法有什么区别?

接收参数:execute()只能执行Runnable类型的任务,submit()可以执行Runnable和Callable类型的任务。
返回值:submit()方法可以返回持有计算结果的Future对象,而execute()没有。
异常处理:submit()的返回值Future调用get方法时,可以捕获处理异常。

15.在java程序中怎么保证多线程的运行安全?

解决原子性问题:JDK Atomic开头的原子类、synchronized、LOCK
解决可见性问题:synchronized、volatile、LOCK
解决有序性问题:Happens-Before规则

16.多线程锁的升级原理是什么?

锁的级别:无锁=>偏向锁=>轻量级锁=>重量级锁
无锁:没有对资源进行锁定,所有线程都可以访问,但是只有一个能修改成功,其他的线程会不断尝试,直至修改成功。
偏向锁:对象的代码一直被同一线程执行,不存在多个线程竞争,偏向锁,指的是偏向第一个加锁线程,该线程不会主动释放偏向锁,只有当其他线程尝试竞争偏向锁时才会被释放。
偏向锁的撤销,需要在某个时间点上没有字节码正在执行时,先暂停拥有偏向锁的线程,然后判断锁对象是否处于被锁定状态。如果线程不处于活动状态,则将对象设置成无锁状态,并撤销偏向锁。如果线程处于活动状态,升级为轻量级锁的状态。
轻量级锁:轻量级锁是指当锁是偏向锁时,被第二个线程B所访问,此时偏向锁会升级为轻量级锁,线程B会通过自旋的形式尝试获取锁,线程不会阻塞,从而提高性能。当前只有一个等待线程,则该线程将通过自旋进行等待。但是当自旋超过一定的次数时,轻量级锁便会升级为重量级锁;当一个线程已持有锁,另一个线程在自旋,而此时又有第三个线程来访时,轻量级锁也会升级为重量级锁。
重量级锁:指当有一个线程获取锁之后,其余所有等待获取该锁的线程都会处于阻塞状态。

17.什么是死锁?

死锁是指两个或两个以上的进程在竞争资源的过程中造成的不可解堵塞。两个线程都在相互等待。

18.怎么防止死锁?

预防:资源一次性分配;可剥夺资源;资源有序分配;超时放弃
避免:银行家算法;
检测:为每个进程和每个资源建立唯一的ID,建立资源分配表和进程等待表
解除:剥夺资源;撤销进程

19.ThreadLocal是什么?有哪些使用场景?

ThreadLocal是线程本地存储,在每个线程中都创建了一个ThresdLocalMap对象,每个线程可以访问自己内部ThreadLocal对象内的value。
经典使用场景是为每个线程分配一个JDBC连接的Connection,这样可以保证每个线程都在各自的Connection上进行数据库的操作,不会出现A线程关了B线程的Connection还有Session管理等问题。

20.说一下synchronized底层实现原理

同步代码块是通过monitorenter和monitorexit指令获取线程的执行权;
同步方法是通过加ACC_SYNCHRONIZED标识实现线程的执行权的控制。

21.synchronized关键字的用法

synchronized关键字可以将对象或方法标记为同步,以实现对对象和方法的互斥访问。可以用synchronized(对象){...}定义同步代码块,或者在声明方法时将synchronized作为方法的修饰符。

22.当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?

不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入。因为非静态方法上的synchronized修饰符要求执行方法时要获得对象的锁,如果已经进入A方法说明对象的锁已经被取走,那么试图进入B方法的线程只能在等锁池中等待对象的锁。

23.synchronized和volatile的区别是什么?

volatile本质是在告诉vm当前变量在寄存器中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其它线程被阻塞。
volatile仅能实现变量的修改可见性,不能保证原子性;synchronized可以保证变量的修改可见性和原子性。
vilatile不会造成线程的阻塞;synchronized可能造成线程的阻塞。
volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。

24.synchronized和Lock有什么区别?

synchronized是关键字,属于jvm层面;Lock是具体类,是api层面的锁。
synchronized无法获取锁的状态;Lock可以判断。
synchronized用于少量同步;Lock用于大量同步。

25.synchronized和ReentrantLock有什么区别?

synchronized代码执行后线程自动释放对锁的占用;ReentrantLock需要手动释放锁。
synchronized不可中断除非抛出异常或执行完成;Reentrantlock可中断。
synchronized非公平锁;Reentrantlock默认非公平锁,也可公平锁。
synchronized要么随机唤醒一个,要么唤醒全部线程;ReentrantLock用来实现分组唤醒需要唤醒的线程,可以精确唤醒。

26.举例说明同步和异步

如果系统中存在临界资源(资源数量少于竞争资源的线程数量),例如正在写的数据以后可能被另外一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就必须进行同步存取(数据库中的排它锁就是最好的例子)。当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
事实上,所谓的同步就是指阻塞式操作,而异步是非阻塞式操作。

27.说一下atomic的原理

作用:多线程下将属性设置为atomic可以保证读取数据的一致性。
CAS(Compare And Swap),乐观锁机制,先比较再交换,以实现原子性。

28.理解乐观锁和悲观锁

乐观锁:认为每次去拿数据的时候别人不会修改,所以不会上锁,但是每次要拿数据的时候都会先判断数据是否被别人修改。
悲观锁:认为每次去拿数据的时候别人都会修改,所以每次都上锁。
使用场景:乐观锁使用于多读少些的应用类型,这样可以提高吞吐量;相反的情况则使用悲观锁。

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

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

相关文章

数据结构修炼——常见的排序算法:插入/希尔/选择/堆排/冒泡/快排/归并/计数

目录 一、常见的排序算法二、常见排序算法的实现2.1 排序算法回顾2.1.1 冒泡排序2.1.2 堆排序 2.2 直接插入排序2.3 希尔排序2.4 选择排序2.5 快速排序2.5.1 快速排序(霍尔法)2.5.2 快速排序(挖坑法)2.5.3 快速排序(前…

极客wordpress模板

这是一个展示WordPress主题的网页设计。页面顶部有一个导航栏,包含多个选项,如“关于我们”、“产品中心”、“案例展示”、“新闻动态”、“联系我们”和“技术支持”。页面中间部分展示了多个产品,每个产品都有一个图片和简短的描述。页面下…

【Linux】冯诺依曼体系结构 OS的概念

🪐🪐🪐欢迎来到程序员餐厅💫💫💫 主厨:邪王真眼 主厨的主页:Chef‘s blog 所属专栏:青果大战linux 总有光环在陨落,总有新星在闪烁 前言废话&#xff1a…

动态链接过程分析

目录 一、前言二、示例程序三、动态库的加载过程1、动态链接器加载动态库2、动态库的加载地址 四、符号重定位1、全局符号表2、全局偏移表 GOT3、liba.so 动态库文件的布局4、liba.so 动态库的虚拟地址5、GOT 表的内部结构6、反汇编 liba.so 代码 五、补充1、延迟绑定 plt 上文…

【ARM】ARM架构参考手册_Part B 内存和系统架构(5)

目录 5.1关于缓存和写缓冲区 5.2 Cache 组织 5.2.1 集联性(Set-associativity) 5.2.2 缓存大小 5.3 缓存类型 5.3.1 统一缓存或分离缓存 5.3.2 写通过(Write-through)或写回(Write-back)缓存 5.3.3…

基于R语言机器学习遥感数据处理与模型空间预测技术及实际项目案例分析

随机森林作为一种集成学习方法,在处理复杂数据分析任务中特别是遥感数据分析中表现出色。通过构建大量的决策树并引入随机性,随机森林在降低模型方差和过拟合风险方面具有显著优势。在训练过程中,使用Bootstrap抽样生成不同的训练集&#xff…

Linux环境配置(学生适用)

1.挑选最便宜的云服务器 如腾讯云服务器,华为云服务器,百度云服务器等等…… 2.找到你的云服务器实例,然后找到你的公网IP。 3.云服务器实例 ---更多 --- 重置root密码 (一定要重置) 4. 下载并安装 xshell 或者其他登陆软件 xshel…

12. 命令行

Hyperf 的命令行默认由 hyperf/command 组件提供,而该组件本身也是基于 symfony/console 的抽象。 一、安装 通常来说该组件会默认存在,但如果您希望用于非 Hyperf 项目,也可通过下面的命令依赖 hyperf/command 组件。 composer require hype…

告别ELK,APO提供基于ClickHouse开箱即用的高效日志方案——APO 0.6.0发布

ELK一直是日志领域的主流产品,但是ElasticSearch的成本很高,查询效果随着数据量的增加越来越慢。业界已经有很多公司,比如滴滴、B站、Uber、Cloudflare都已经使用ClickHose作为ElasticSearch的替代品,都取得了不错的效果&#xff…

【Golang】Go语言中如何创建Cron定时任务

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

MySQL【知识改变命运】11

联合查询 6. ⼦查询6.1 语法6.2 单⾏⼦查询6.3 多⾏⼦查询6.4 多列⼦查询6.5 在from⼦句中使⽤⼦查询 7. 合并查询7.1 创建新表并初始化数据7.2 Union7.3 Union all 8. 插⼊查询结果8.1 语法8.2 ⽰例 6. ⼦查询 ⼦查询是把⼀个SELECT语句的结果当做别⼀个SELECT语句的条件&…

10.22 MySQL

存储过程 存储函数 存储函数是有返回值的存储过程,存储函数的参数只能是in类型的。具体语法如下: characteristic 特性 练习: 从1到n的累加 ​​​​​​ create function fun1(n int) returns int deterministic begindeclare total i…

制氮机分子筛的作用

制氮机作为一种重要的工业设备,广泛应用于食品、饮料、化学、石油、电子和医疗保健等多个行业。其核心组件之一——分子筛。本文将详细探讨制氮机分子筛的作用及其重要性。 一、分子筛的基本概念 分子筛是一种具有均匀孔径的多孔材料,常用于气体分离和纯…

Elasticsearch 中的高效按位匹配

作者:来自 Elastic Alexander Marquardt 探索在 Elasticsearch 中编码和匹配二进制数据的六种方法,包括术语编码(我喜欢的方法)、布尔编码、稀疏位位置编码、具有精确匹配的整数编码、具有脚本按位匹配的整数编码以及使用 ESQL 进…

基于vue框架的的二手车交易系统的设计与实现thx7v(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能:用户,卖家,车辆类型,二手车,在线留言,订单信息 开题报告内容 基于Vue框架的二手车交易系统的设计与实现开题报告 一、课题背景及意义 随着汽车消费市场的日益成熟与消费者换车频率的增加,二手车交易市场逐渐成为汽车市场的…

pycharm配置git版本控制

今天记录一下如何在pycharm工具中配置git版本控制,主要分以下步骤: 1、安装git 首先需要有git环境,去git官网下载git安装包,下一步下一步执行安装完成即可 2、在pycharm中配置git路径 下载git后,在pycharm的 setti…

「AIGC」n8n AI Agent开源的工作流自动化工具

n8n AI Agent 是一个利用大型语言模型(LLMs)来设计和构建智能体(agents)的工具,这些智能体能够执行一系列复杂的任务,如理解指令、模仿类人推理,以及从用户命令中理解隐含意图。n8n AI Agent 的核心在于构建一系列提示(prompts),使 LLM 能够模拟自主行为。 传送门→ …

GAMES104:17 游戏引擎的玩法系统:高级AI-学习笔记

文章目录 课前QA一,层次任务网络(Hierarchical Tasks Network,HTN)1.1 HTN Framework1.2 HTN Task Types1.2.1 Primitive Task基本任务1.2.2 Compound Task符合任务 1.3 Planning1.4 Replan1.5 总结 二,目标导向行为规…

在ECS实例上搭建WordPress博客平台

WordPress是使用PHP语言开发的博客平台,在支持PHP和MySQL数据库的服务器上,您可以用WordPress搭建自己的网站,也可以用作内容管理系统(CMS)。本教程介绍如何在不同操作系统的ECS实例上,手动搭建WordPress网…

SonarQube快速实践

SonarQube快速实践 1. 简介 SonarQube 是一个本地部署的代码分析工具,旨在检测30多种编程语言、框架和基础设施即代码(IaC)平台中的代码问题。通过直接集成到您的持续集成(CI)流水线中或在我们支持的DevOps平台之一上…