当前位置: 首页 > news >正文

面试 Java 并发编程八股文十问十答第四期

面试 Java 并发编程八股文十问十答第四期

作者:程序员小白条,个人博客

相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新!

⭐点赞⭐收藏⭐不迷路!⭐

1)Java 中你怎样唤醒一个阻塞的线程?

要唤醒一个阻塞的线程,通常需要使用wait()notify()notifyAll() 方法配合使用。下面是一般的步骤:

  1. 在同步代码块中调用 wait() 方法使线程进入等待状态。
  2. 当某个条件满足时,调用 notify()notifyAll() 方法唤醒等待的线程。
  3. 被唤醒的线程会重新竞争对象锁,一旦获得锁,就可以继续执行。
synchronized (monitor) {while (condition) {monitor.wait(); // 线程进入等待状态}// 满足条件后唤醒线程monitor.notify(); // 或者 monitor.notifyAll();
}

2)notify() 和 notifyAll() 有什么区别?

  • notify() 方法用于唤醒等待队列中的一个线程,具体唤醒哪个线程取决于调度器的选择。
  • notifyAll() 方法用于唤醒等待队列中的所有线程,让它们有机会竞争对象锁。

通常情况下,如果只有一个线程需要被唤醒,可以使用 notify() 方法以减少不必要的竞争。但是,如果有多个线程需要被唤醒,或者不确定有多少线程需要唤醒时,可以使用 notifyAll() 方法确保所有等待的线程都有机会继续执行。

3)如何在两个线程间共享数据?

在 Java 中,两个线程之间共享数据的常见方式包括使用共享对象或者使用线程间通信机制。以下是一些常见的方法:

  1. 共享对象:两个线程可以共享同一个对象,通过对象的成员变量来共享数据。需要确保线程安全,可以使用同步方法或同步块来保护共享数据的访问。
  2. 线程间通信:可以使用 wait()notify()notifyAll() 等方法来实现线程间的通信。一个线程在等待某个条件满足时调用 wait() 进入等待状态,另一个线程在满足条件时调用 notify()notifyAll() 唤醒等待的线程。
  3. 线程安全的数据结构:使用线程安全的数据结构,比如 ConcurrentHashMapConcurrentLinkedQueue 等,来实现线程间的数据共享。
  4. 使用锁:可以使用 ReentrantLocksynchronized 关键字来保护共享数据的访问,确保线程安全。

在实现线程间数据共享时,需要注意线程安全性和避免发生竞态条件,以确保多线程环境下的数据一致性和正确性。

4)Java 如何实现多线程之间的通讯和协作?

在 Java 中,多线程之间的通讯和协作可以通过以下方式实现:

  1. 使用共享对象:多个线程共享同一个对象,通过对象的成员变量进行通讯。可以使用 wait()notify()notifyAll() 方法实现线程间的等待和唤醒。
  2. 使用线程安全的队列:可以使用 BlockingQueue 或其他线程安全的数据结构来实现线程之间的数据传递和协作。
  3. 使用信号量Semaphore 类可以用来控制同时访问共享资源的线程数量,实现线程之间的协作。
  4. 使用 CountDownLatch 和 CyclicBarrierCountDownLatchCyclicBarrier 类可以用来实现多个线程之间的协作和同步。
  5. 使用 Lock 和 ConditionReentrantLockCondition 类可以实现更灵活的线程协作机制。

5)同步方法和同步块,哪个是更好的选择?

在选择同步方法和同步块时,取决于具体情况。一般来说:

  • 同步方法:使用同步方法可以简化代码,因为整个方法体都会被同步,不需要显式地编写同步代码块。但是同步方法的粒度比较粗,可能会影响程序的性能。
  • 同步块:使用同步块可以精确地控制需要同步的代码块,避免不必要的同步,提高程序的性能。但是需要显式地编写同步代码块,增加了代码的复杂性。

一般来说,如果需要同步的代码比较少,可以考虑使用同步块;如果整个方法都需要同步,可以考虑使用同步方法。在实际应用中,需要根据具体情况进行权衡和选择。

6)什么是线程同步和线程互斥,有哪几种实现方式?

  • 线程同步:线程同步是指多个线程之间按照一定的顺序执行,保证共享资源的正确访问。线程同步可以避免竞态条件和数据不一致的问题。
  • 线程互斥:线程互斥是指多个线程在访问共享资源时,通过加锁的方式实现互斥访问,即同一时刻只有一个线程可以访问共享资源,其他线程需要等待。

几种实现线程同步和线程互斥的方式包括:

  1. 使用 synchronized 关键字:可以在方法上或代码块中使用 synchronized 关键字来实现线程同步和互斥。
  2. 使用 Lock 接口ReentrantLock 类提供了与synchronized 关键字类似的功能,可以更灵活地控制锁的获取和释放。
  3. 使用 volatile 关键字volatile 关键字可以保证变量的可见性,但不能保证原子性,适用于简单的标志位等情况。
  4. 使用 wait()、notify() 和 notifyAll():通过这些方法可以实现线程之间的等待和唤醒,实现线程间的协作和互斥。
  5. 使用并发容器:Java 中的并发容器如 ConcurrentHashMapConcurrentLinkedQueue 等提供了线程安全的数据结构,可以避免手动加锁。

选择合适的线程同步和互斥方式取决于具体的需求和场景,需要根据实际情况进行选择和权衡。

7)在监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?

在 Java 中,监视器(Monitor)是通过对象的内置锁(也称为监视器锁)来实现线程同步的。当一个线程进入一个 synchronized 方法或代码块时,它会尝试获取对象的内置锁,如果锁已经被其他线程持有,则该线程会被阻塞,直到锁被释放。

程序应该根据需要选择合适的同步级别,可以在方法级别或代码块级别进行同步。一般来说,推荐使用更细粒度的同步,即在尽可能小的代码块中加锁,以减少同步的范围,提高程序的性能。

8)如果你提交任务时,线程池队列已满,这时会发生什么?

当线程池队列已满时,如果线程池中的线程数量未达到最大线程数限制,新提交的任务会尝试创建新的线程来执行。如果线程池中的线程数量已经达到最大线程数限制,且队列已满,则根据线程池的拒绝策略来处理新提交的任务。

常见的拒绝策略包括:

  • AbortPolicy:直接抛出 RejectedExecutionException 异常。
  • CallerRunsPolicy:由提交任务的线程来执行这个任务。
  • DiscardPolicy:直接丢弃新任务,不抛出异常。
  • DiscardOldestPolicy:丢弃队列中等待时间最长的任务,然后尝试重新提交新任务。

可以根据具体的业务需求选择合适的拒绝策略,或者自定义拒绝策略来处理任务提交时线程池队列已满的情况。

9)什么叫线程安全?servlet 是线程安全吗?

线程安全指的是在多线程环境下,对共享数据的访问操作不会导致数据出现异常或不一致的情况。线程安全的代码能够正确地处理多个线程并发访问共享数据的情况,保证数据的一致性和正确性。

对于 Servlet,Servlet 容器会为每个请求创建一个线程来处理,因此 Servlet 的实现需要是线程安全的。Servlet 容器会在多个线程之间共享同一个 Servlet 实例,因此 Servlet 类中的实例变量需要考虑线程安全性。

通常情况下,Servlet 应该遵循以下原则来确保线程安全:

  • 避免使用实例变量存储请求相关的数据,可以使用局部变量或者 synchronized 来处理共享数据。
  • 如果需要使用实例变量,确保对共享数据的访问是线程安全的,可以使用 synchronized 或其他线程安全的方式来保护数据访问。

10)在 Java 程序中怎么保证多线程的运行安全?

要保证多线程的运行安全,可以采取以下措施:

  1. 使用同步机制:使用 synchronized 关键字或 Lock 接口来保护共享数据的访问,确保在同一时刻只有一个线程可以访问共享资源。
  2. 使用线程安全的数据结构:使用 Java 提供的线程安全的数据结构,如 ConcurrentHashMap、ConcurrentLinkedQueue 等,避免手动加锁。
  3. 避免竞态条件:在编写多线程程序时,要注意避免竞态条件的发生,即多个线程同时对共享资源进行读写而导致数据不一致的情况。
  4. 使用 volatile 关键字:在需要保证变量可见性的情况下,可以使用 volatile 关键字来修饰变量,确保线程之间的数据同步。
  5. 使用线程池:合理使用线程池可以避免线程创建和销毁的开销,同时可以控制并发线程数量,提高程序的性能和稳定性。
  6. 避免死锁:在设计多线程程序时,要避免出现死锁情况,即多个线程相互等待对方释放资源而无法继续执行的情况。

通过以上措施,可以有效地保证多线程程序的运行安全,确保数据的一致性和正确性。

开源项目地址:https://gitee.com/falle22222n-leaves/vue_-book-manage-system

前后端总计已经 800+ Star,1.5W+ 访问!

⭐点赞⭐收藏⭐不迷路!⭐

相关文章:

面试 Java 并发编程八股文十问十答第四期

面试 Java 并发编程八股文十问十答第四期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新! ⭐点赞⭐收藏⭐不迷路!⭐ 1)Java 中你怎样唤醒…...

物体检测-系列教程27:YOLOV5 源码解析17(训练脚本解读:训练函数4)

😎😎😎物体检测-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 点我下载源码 24、epoch循环训练------更新、评估、保存 这部分是训练过程的每个epoch结束之前执行的一…...

基于51单片机的数字时钟(万年历)设计与实现

基于51单片机的数字时钟(万年历)设计与实现 摘要 随着科技的不断发展,数字时钟已成为人们日常生活中不可或缺的一部分。基于51单片机的数字时钟(万年历)设计,结合了传统时钟的功能与现代电子技术&#xf…...

2024年谷歌SEO的趋势预测及应对建议(川圣SEO)蜘蛛池

baidu搜索:如何联系八爪鱼SEO? baidu搜索:如何联系八爪鱼SEO? baidu搜索:如何联系八爪鱼SEO? 虽然说“SEO”已死这个口号已经喊了很多年了(最终也没死),但是在2023年很…...

Rust 生命周期符号使用的方法和规律

一、生命周期符号使用的规律 在 Rust 中,生命周期(lifetimes)是用于处理引用和所有权问题的关键概念。生命周期符号(通常表示为 a、b 等)用于指定引用的有效时间范围。这有助于编译器确保在引用被使用时,所…...

生成哈夫曼树(100%用例)C卷(JavaPythonC++Node.jsC语言)

给定长度为n的无序的数字数组,每个数字代表二叉树的叶子节点的权值,数字数组的值均大于等于1。请完成一个函数,根据输入的数字数组,生成哈夫曼树,并将哈夫曼树按照中序遍历输出。 为了保证输出的二又树中序遍历结果统一,增加以下限制:二叉树节点中,左节点权值小于等于右…...

el-form-item内的el-select如何自适应宽度

最近在使用element-ui做后台管理的时候,有个需求是在弹窗组件里面,添加一个el-select下拉框选项,但是给el-select设置的宽度无法自适应,原因很简单,我们不需要设置固定宽度,设置百分比就行了,让…...

什么洗地机值得推荐?旗舰洗地机希亦、追觅、西屋、海尔实际表现如何?

洗地机这个产品相信大家已经不陌生了,它集合吸尘器和电动扫地拖把的功能,轻轻推拉便可以解决地面上的赃物,且不用我们手动清洗滚刷,深得家务人的喜爱,可是,当我们真正要去选购的时候,还是很纠结…...

掘根宝典之C++隐式类型转化(整型提升,算术转换)

赋值中的隐式转换 话不多说,我们直接看例子 bool b42; //b为真 int ib; //i的值为1 i3.14; //i的值为3 double pi i; // pi的值为3.0 unsigned char c -1; // 假设char占8比特,c的值为255 s…...

group by order by having where union

力扣题目链接 having where 区别 having子句用于分组后筛选,where子句用于行条件筛选 having一般都是配合group by 和聚合函数一起出现如(count(),sum(),avg(),max(),min()) where条件子句中不能使用聚集函数,而having子句就可以。 having只能用在group…...

微信私信短剧机器人源码

本源码仅提供参考,有能力的继续开发 接口为api调用 云端同步 https://ys.110t.cn/api/ajax.php?actyingshilist 影视搜索 https://ys.110t.cn/api/ajax.php?actsearch&name剧名 每日更新 https://ys.110t.cn/api/ajax.php?actDaily 反馈接口 https://ys.11…...

java使用ws.schild.jave将视频转成mp4

<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://…...

python map函数

python map函数 文章目录 python map函数 在Python中&#xff0c; map()函数用于将一个函数应用于可迭代对象&#xff08;如列表或元组&#xff09;中的每个元素&#xff0c;并返回一个包含结果的新的可迭代对象。 map()函数的语法如下&#xff1a; map(function, iterable)其…...

基于SSM的党务政务服务热线平台(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的党务政务服务热线平台&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spri…...

Unity3D 动态生成场景管理节点详解

前言 Unity3D 提供了丰富的功能和工具&#xff0c;可以帮助开发者快速高效地创建各种类型的游戏。在游戏开发过程中&#xff0c;有时候我们需要动态生成场景管理节点来管理游戏场景中的各种元素&#xff0c;比如角色、道具、敌人等。本文将详细介绍如何在Unity3D中动态生成场景…...

js--构造函数

创建对象的方式&#xff1a; 1、利用对象字面量{}创建 const arr {name: tom,age: 18 } 2、利用js内置构造&#xff08;Object&#xff0c;Array&#xff0c;String&#xff0c;Number&#xff09;函数 var obj new Object() //创建一个空的对象 obj.uname tom obj.age 2…...

Tomcat目录结构

文章目录 binconfliblogswebapp bin 存放tomcat的可执行程序 从上图可以看出bin中的文件主要是两种文件&#xff0c;一种是.bat一种是.sh .bat:主要用于windows .sh:主要用于linux .bat文件是Windows操作系统中的批处理文件。它是一种简单的文本文件&#xff0c;其中包含了一…...

读西游记第一回:西游记世界格局

天地之数&#xff1a; 元&#xff1a;十二万九千六百岁&#xff08;129600年&#xff09; 1元12会&#xff1a;子、丑、寅、卯、巳、午、未、申、酉、戌、亥。每会18000年。与12地支对应。 亥会期&#xff1a;前5400年混沌期&#xff0c;后5400年&#xff0c;盘古开天辟地&am…...

【Unity知识点详解】Button点击事件拓展,单击、双击、长按实现

Button拓展 今天来聊一下关于Button的事件拓展&#xff0c;这里只是拿Button来举例&#xff0c;Unity中其他的UI组件如Toggle、Slider等都也适用。 我们知道在Button中我们可以通过onClick的方式来添加点击事件&#xff0c;但在游戏开发过程中我们往往对Button有着更多的功能需…...

了解财富的本质才能知道自己几斤几两

生活在现代都市中&#xff0c;经历了经济的潮起潮落。在一望无际的楼宇下&#xff0c;是每天匆忙工作的一个个鲜活个体。有的在为了生存而工作&#xff0c;有的在享受着惬意的时光&#xff0c;有人行色匆匆&#xff0c;目光所及之处&#xff0c;尽是可遇不可求的机会。成为中产…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...