JavaEE必会面试题,从线程讲到线程安全,一文带你通过多线程面试
目录一、讲讲线程与进程的联系二、线程创建的五种写法三、产生线程安全问题的五大原因四、线程的状态有哪几种五、死锁产生的四个必要条件[背下来]六、如何避免死锁七、请你写一个懒汉模式线程安全的代码并解释你这样写的原因你的回答从这个专题开始我将开始讲解一些Java后端面试准备过程中必须具备的素养与能力废话不多说今天主要学习的是Java多线程编程中最最重要的基础面试题也是工作中最可能用到的内容。一、讲讲线程与进程的联系首先解释定义即进程是计算机运行起来的应用程序如下图线程是轻量级进程和进程的关系是一个进程包含多个线程。他们之间的区别重点记忆1. 每个进程有自己独立的资源进程与进程间不能共享而同一个进程的线程之间共享相同的资源。2. 进程之间不会相互影响进程挂了不会影响其他进程而同一个进程的某个线程挂了有可能把其他线程带走。3. 进程之间通常不会有“资源冲突”的情况而同一个进程的线程之间特别容易产生资源访问冲突。4. 进程是操作系统资源分配的基本单位线程是操作系统调度执行的基本单位二、线程创建的五种写法1. 继承Thread重写run方法run方法是多线程代码执行的入口由start调用package thread; // 创建一个新的类, 让这个类继承标准库的 Thread 类 class MyThread extends Thread { // 重写父类的 run 方法. Override public void run() { while (true) { System.out.println(hello thread); // 休息 1000ms 1s try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } // Demo 例子~~ Example Sample Tutor 入门的例子 public class Demo1 { public static void main(String[] args) throws InterruptedException { // 1. 创建 Thread 的实例 // MyThread t new MyThread(); Thread t new MyThread(); Thread t2 new MyThread(); Thread t3 new MyThread(); // 2. 启动线程 t.start(); t2.start(); t3.start(); // t.run(); while (true) { System.out.println(hello main); Thread.sleep(1000); } } }2. 实现Runnable接口搭配Threadpackage thread; import java.util.Scanner; class MyRunnable implements Runnable { Override public void run() { while (true) { System.out.println(hello thread); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } public class Demo2 { public static void main(String[] args) throws InterruptedException { MyRunnable r new MyRunnable(); Thread t new Thread(r); t.start(); while (true) { System.out.println(hello main); Thread.sleep(1000); } } }3. 继承Thread使用匿名内部类package thread; public class Demo3 { public static void main(String[] args) throws InterruptedException { Thread t new Thread() { Override public void run() { while (true) { System.out.println(hello thread); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } } }; // 记住, 调用 start 才是真正创建线程. t.start(); while (true) { System.out.println(hello main); Thread.sleep(1000); } } }4. 继承Runnable使用匿名内部类package thread; public class Demo4 { public static void main(String[] args) throws InterruptedException { // Runnable runnable new Runnable() { // Override // public void run() { // // } // }; // Thread t new Thread(runnable); Thread t new Thread(new Runnable() { Override public void run() { while (true) { System.out.println(hello thread); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } } }); t.start(); while (true) { System.out.println(hello main); Thread.sleep(1000); } } }5. Lambda表达式最常用package thread; public class Demo5 { public static void main(String[] args) throws InterruptedException { Thread t new Thread(() - { while (true) { System.out.println(hello thread); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); t.start(); while (true) { System.out.println(hello main); Thread.sleep(1000); } } }三、产生线程安全问题的五大原因1.根本原因操作系统对于线程的调度是随机的这个我们改不了2.两个线程对同一个变量进行修改操作不是常见的Java应对方式2.1 一个线程针对一个变量进行修改 没问题2.2 两个线程针对不同变量进行修改 没问题2.3 两个线程针对同一个变量进行读取 没问题针对2.1-不使用多线程 单线程 没法充分利用多核 CPU 资源~针对2.2-不使用同一个变量, 每个线程搞一个变量 (比较吃的需求和逻辑的)3.修改操作不是原子的-解决方式使用锁比如synchronized4.内存可见性问题由于编译器优化产生的线程安全问题可以从JMM模型主内存和工作内存或者硬件的角度去给面试官解释一句话“从寄存器或者缓存中读数据而不是从内存中读数据”--解决使用volatile5.指令重排序问题只有单例模式一个孤证后面会讲有关懒汉模式的线程安全的代码四、线程的状态有哪几种1宏观上理解分为阻塞态和就绪态2微观上理解分为NEW创建了线程但是还没有start()TERMINATED线程结束了但是Thread对象还没有销毁RUNNABLE线程正在CPU上运行或者正在就绪队列中即将被操作系统调度到CPU上执行WAITING死等--join()TIMED_WATING带有超时时间的等待--join(填写毫秒)BLOCKED与锁有关的阻塞五、死锁产生的四个必要条件[背下来]1. 锁是互斥的--同一时刻只能有一个线程拿到锁2. 锁是不可被抢占的1、2对于synchronized是改不了的3. 请求和保持在已经持有一把锁且还未释放的前提下又去申请另一把锁典型的“吃着碗里的想着锅里的”4. 循环等待 / 环路等待类比车钥匙锁家里家钥匙锁车里六、如何避免死锁1. 打破请求和保持避免“锁的嵌套”2. 打破循环等待约定好一个加锁的顺序这里附上一个典型的示例代码如下package thread; //5.多线程3 解决典型死锁--打破循环等待--按照一定的顺序来加锁即可 public class Demo18_2 { private static void sleep(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { throw new RuntimeException(e); } } public static void main(String[] args) { Object locker1 new Object(); Object locker2 new Object(); Thread t1 new Thread(() - { synchronized (locker1) { System.out.println(t1 获取到 locker1); sleep(1000); synchronized (locker2) { System.out.println(t1 获取到 locker2); } } }); Thread t2 new Thread(() - { synchronized (locker1) { System.out.println(t2 获取到 locker1); sleep(1000); synchronized (locker2) { System.out.println(t2 获取到 locker2); } } }); t1.start(); t2.start(); } }七、请你写一个懒汉模式线程安全的代码并解释你这样写的原因package thread; // 懒汉的单例模式 class SingletonLazy { private volatile static SingletonLazy instance null; // 作为要加锁的对象. 由于是要在 static 方法中使用锁对象, 对象本身也得是 static 的. private static Object locker new Object(); // 懒汉模式的关键在于, 把实例的创建时机推迟了, 推迟到第一次使用的时候, 创建. public static SingletonLazy getInstance() { // 这个条件判定是否需要加锁 if (instance null) { synchronized (locker) { // 判定是否需要创建实例 if (instance null) { instance new SingletonLazy(); } } } return instance; } private SingletonLazy() { } } public class Demo25 { public static void main(String[] args) { SingletonLazy s1 SingletonLazy.getInstance(); SingletonLazy s2 SingletonLazy.getInstance(); System.out.println(s1 s2); } }你的回答“面试官你好这个懒汉模式的线程安全代码的要点有这么三点第一使用synchronized保证判断和赋值操作在一起是原子的保证线程安全第二使用双重if内层if用来判断是否需要创建实例而外层if判断用来判断是否需要加锁因为加锁涉及到开销和效率问题第三为instance加上volatile关键字来防止因为指令重排序导致的线程安全问题”特别注意懒汉模式只有在第一次创建实例之前会产生线程安全问题一旦创建实例成功了线程安全问题就消失了所以为了避免反复加锁带来的开销需要在synchronized的外层也加上一个if判断语句

相关新闻

从零开始搭建飞书智能助手——第一步:引入SpringBoot、FastApi实现与助手对话

从零开始搭建飞书智能助手——第一步:引入SpringBoot、FastApi实现与助手对话

用 Spring Boot FastAPI 搭建飞书 AI 个人助理 整体架构 DeepSeek APIbutler-agent :8000personal-butler :8080飞书开放平台飞书用户DeepSeek APIbutler-agent :8000personal-butler :8080飞书开放平台飞书用户#mermaid-svg-0SInvsHFDtAyoEfO{font-family:"trebuchet m…

2026/6/27 6:14:37阅读更多 →
Java毕设项目:基于 SpringBoot 技术的社区智能化健康服务系统的设计与实现 基于 SpringBoot 的社区健康数据管理系统 (源码+文档,讲解、调试运行,定制等)

Java毕设项目:基于 SpringBoot 技术的社区智能化健康服务系统的设计与实现 基于 SpringBoot 的社区健康数据管理系统 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/6/27 6:14:37阅读更多 →
短视频矩阵运营是否适合中小企业

短视频矩阵运营是否适合中小企业

在数字化营销快速发展的今天,越来越多的中小企业开始关注短视频矩阵运营。但对于资源有限、团队不完善的中小企业来说,这种模式是否真的适合?本文将从行业背景、企业需求、服务模式等角度展开分析,帮助读者更全面地理解这一问题。…

2026/6/27 6:14:37阅读更多 →
前端交互动效实现

前端交互动效实现

前端交互动效实现:提升用户体验的关键 在当今的Web开发中,前端交互动效已成为提升用户体验的重要手段。无论是按钮点击反馈、页面过渡动画,还是复杂的滚动视差效果,精心设计的动效都能让用户感受到流畅与愉悦。随着CSS3、JavaScr…

2026/6/27 7:24:40阅读更多 →
电子厂SMT产线排程优化:JVS-APS提升设备利用率28%

电子厂SMT产线排程优化:JVS-APS提升设备利用率28%

摘要 SMT(表面贴装技术)产线是电子制造的核心环节,其排程复杂度高、换线频繁、设备利用率直接影响产能和交付。本文以电子制造企业的SMT产线APS实施案例为背景,详细阐述JVS-APS系统的选型过程、排程算法优化方案及上线效果。企业…

2026/6/27 7:24:40阅读更多 →
软件服务定位器管理化的服务查找获取

软件服务定位器管理化的服务查找获取

软件服务定位器管理化的服务查找获取:现代架构的核心枢纽 在分布式系统和微服务架构盛行的今天,服务的高效查找与动态获取成为开发中的关键挑战。软件服务定位器(Service Locator)作为一种设计模式,通过集中化管理服务…

2026/6/27 7:24:40阅读更多 →
系统日志收集分析

系统日志收集分析

系统日志收集分析:企业运维的智慧之眼 在数字化时代,系统日志是记录服务器、应用程序和网络设备运行状态的重要数据。无论是排查故障、优化性能,还是防范安全威胁,日志分析都扮演着关键角色。面对海量日志,如何高效收…

2026/6/27 7:24:40阅读更多 →
HS2-HF Patch:5分钟快速部署,解锁HoneySelect2终极游戏体验

HS2-HF Patch:5分钟快速部署,解锁HoneySelect2终极游戏体验

HS2-HF Patch:5分钟快速部署,解锁HoneySelect2终极游戏体验 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch HS2-HF Patch是一款专为Hone…

2026/6/27 7:24:40阅读更多 →
新一代 YL1621 011A 版本LCD 驱动 IC 重磅升级,便携设备显示方案首选

新一代 YL1621 011A 版本LCD 驱动 IC 重磅升级,便携设备显示方案首选

导语做电动自行车仪表、智能温控面板、家用血压计、NB-IoT 水表的硬件工程师,一定都遇到过两大痛点:电池供电设备续航拉胯、高低温 / 电压波动环境屏幕闪屏、静电死机。 2026 全新迭代 YL1621(011A 新版本),对比旧版 0…

2026/6/27 7:19:39阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/26 11:03:22阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/27 5:46:02阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/26 9:29:01阅读更多 →
10分钟AI语音克隆与实时变声:Retrieval-based-Voice-Conversion-WebUI完整指南

10分钟AI语音克隆与实时变声:Retrieval-based-Voice-Conversion-WebUI完整指南

10分钟AI语音克隆与实时变声&#xff1a;Retrieval-based-Voice-Conversion-WebUI完整指南 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrie…

2026/6/27 0:04:03阅读更多 →
Layerdivider:3分钟AI智能分层,彻底告别手动抠图时代

Layerdivider:3分钟AI智能分层,彻底告别手动抠图时代

Layerdivider&#xff1a;3分钟AI智能分层&#xff0c;彻底告别手动抠图时代 【免费下载链接】layerdivider A tool to divide a single illustration into a layered structure. 项目地址: https://gitcode.com/gh_mirrors/la/layerdivider 还在为复杂的图像分层工作烦…

2026/6/27 0:04:03阅读更多 →
Tomcat中X-Frame-Options配置实战:防御点击劫持的四种方法与最佳实践

Tomcat中X-Frame-Options配置实战:防御点击劫持的四种方法与最佳实践

1. 项目概述&#xff1a;为什么X-Frame-Options是Web安全的“防盗门”&#xff1f;最近在排查一个老项目的安全审计报告时&#xff0c;又被提到了“点击劫持”风险&#xff0c;矛头直指缺失的X-Frame-Options响应头。这已经不是第一次了&#xff0c;很多开发团队&#xff0c;尤…

2026/6/27 0:04:03阅读更多 →