0

0

Java线程面试题的相关知识点有哪些?

WBOY

WBOY

发布时间:2023-04-23 23:07:06

|

1292人浏览过

|

来源于亿速云

转载

java线程面试题的知识点有哪些

一、sychronied 修饰普通方法和静态方法的区别?什么是可见性?

对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的 class 对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个 class 对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。
       有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存 在的,类锁其实锁的是每个类的对应的 class 对象。类锁和对象锁之间也是互不干扰的。
       可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
       由于线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量,那么对于共享变量 V,它们首先是在自己的工作内存,之后再同步到主内存。可是并不会及时的刷到主存中,而是会有一定时间差。很明显,这个时候线程 A 对变量 V 的操作对于线程 B 而言就不具备可见性了 。
       要解决共享对象可见性这个问题,我们可以使用 volatile 关键字或者是加锁。

二、锁分为哪几类。

Java线程面试题的知识点有哪些

三、CAS 无锁编程的原理。

使用当前的处理器基本都支持 CAS()的指令,只不过每个厂家所实现的算法并不一样,每一个 CAS 操作过程都包含三个运算符:一个内存地址 V,一个期望的值 A 和一个新值 B,操作的时候如果这个地址上存放的值等于这个期望的值 A,则将地址上的值赋为新值 B,否则不做任何操作。
       CAS 的基本思路就是,如果这个地址上的值和期望的值相等,则给其赋予新值, 否则不做任何事儿,但是要返回原值是多少。循环 CAS 就是在一个循环里不断的 做 cas 操作,直到成功为止。 还可以说说 CAS 的三大问题。

四、ReentrantLock 的实现原理。

线程可以重复进入任何一个它已经拥有的锁所同步着的代码块, synchronized、ReentrantLock 都是可重入的锁。在实现上,就是线程每次获取锁时判定如果获得锁的线程是它自己时,简单将计数器累积即可,每释放一次锁, 进行计数器累减,直到计算器归零,表示线程已经彻底释放锁。底层则是利用了 JUC 中的 AQS 来实现的。

立即学习Java免费学习笔记(深入)”;

五、AQS 原理。

是用来构建锁或者其他同步组件的基础框架,比如 ReentrantLock、 ReentrantReadWriteLock 和 CountDownLatch 就是基于 AQS 实现的。它使用了一 个 int 成员变量表示同步状态,通过内置的 FIFO 队列来完成资源获取线程的排队工作。它是 CLH 队列锁的一种变体实现。它可以实现 2 种同步方式:独占式,共 享式。
       AQS 的主要使用方式是继承,子类通过继承 AQS 并实现它的抽象方法来管理同步状态,同步器的设计基于模板方法模式,所以如果要实现我们自己的同步工具类就需要覆盖其中几个可重写的方法,如 tryAcquire、tryReleaseShared 等等。
       这样设计的目的是同步组件(比如锁)是面向使用者的,它定义了使用者与同步组件交互的接口(比如可以允许两个线程并行访问),隐藏了实现细节;同步器面向的是锁的实现者,它简化了锁的实现方式,屏蔽了同步状态管理、线程的排队、等待与唤醒等底层操作。这样就很好地隔离了使用者和实现者所需关注的领域。
       在内部,AQS 维护一个共享资源 state,通过内置的 FIFO 来完成获取资源线程的排队工作。该队列由一个一个的 Node 结点组成,每个 Node 结点维护一个 prev 引用和 next 引用,分别指向自己的前驱和后继结点,构成一个双端双向链 表。

六、Synchronized 的原理以及与ReentrantLock 的区别。

synchronized (this)原理:涉及两条指令:monitorenter,monitorexit;再说同步方法,从同步方法反编译的结果来看,方法的同步并没有通过指令 monitorenter 和 monitorexit 来实现,相对于普通方法,其常量池中多了 ACC_SYNCHRONIZED 标示符。
       JVM 就是根据该标示符来实现方法的同步的:当方法被调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取 monitor,获取成功之后才能执行方法体,方法执行完后再释放 monitor。在方法执行期间,其他任何线程都无法再获得同一个 monitor 对象。

七、Synchronized 做了哪些优化

引入如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁、逃逸分析等技术来减少锁操作的开销。

  • 逃逸分析:如果证明一个对象不会逃逸方法外或者线程外,则可针对此变量进行优化:

  • 同步消除: synchronization Elimination,如果一个对象不会逃逸出线程,则对此变量的同步措施可消除。

  • 锁消除和粗化锁消除:虚拟机的运行时编译器在运行时如果检测到一些要求同步的代码上不可能发生共享数据竞争,则会去掉这些锁。

  • 锁粗化:将临近的代码块用同一个锁合并起来。 消除无意义的锁获取和释放,可以提高程序运行性能。

八、Synchronized static 与非 static 锁的区别和范围。

对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的 class 对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个 class 对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。
       有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存 在的,类锁其实锁的是每个类的对应的 class 对象。类锁和对象锁之间也是互不干扰的。

九、volatile 能否保证线程安全?在 DCL 上的作用是什么?

不能保证,在 DCL 的作用是:volatile 是会保证被修饰的变量的可见性和有序性, 保证了单例模式下,保证在创建对象的时候的执行顺序一定是

  1. 分配内存空间

  2. 实例化对象 instance

  3. 把 instance 引用指向已分配的内存空间,此时 instance 有了内存地址,不再为 null 了的步骤, 从而保证了 instance 要么为 null 要么是已经完全初始化好的对象。

十、volatile 和 synchronize 有什么区别?

volatile 是最轻量的同步机制。 volatile 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。但是 volatile 不能保证操作的原子性,因此多线程下的写复合操作会导致线程安全问题。
       关键字 synchronized 可以修饰方法或者以同步块的形式来进行使用,它主要确保多个线程在同一个时刻,只能有一个线程处于方法或者同步块中,它保证了线程对变量访问的可见性和排他性,又称为内置锁机制。

十一、什么是守护线程?你是如何退出一个线程的?

Daemon(守护)线程是一种支持型线程,因为它主要被用作程序中后台调 度以及支持性工作。这意味着,当一个 Java 虚拟机中不存在非 Daemon 线程的时候,Java 虚拟机将会退出。可以通过调用 Thread.setDaemon(true)将线程设置为 Daemon 线程。我们一般用不上,比如垃圾回收线程就是 Daemon 线程。
       线程的中止:要么是 run 执行完成了,要么是抛出了一个未处理的异常导致线程提前结束。 暂停、恢复和停止操作对应在线程 Thread 的 API 就是 suspend()、resume()和 stop()。 但是这些 API 是过期的,也就是不建议使用的。因为会导致程序可能工作在不确定状态下。
       安全的中止则是其他线程通过调用某个线程 A 的 interrupt()方法对其进行中断操作,被中断的线程则是通过线程通过方法 isInterrupted()来进行判断是否被中断, 也可以调用静态方法 Thread.interrupted()来进行判断当前线程是否被中断,不过 Thread.interrupted()会同时将中断标识位改写为 false。

Insou AI
Insou AI

Insou AI 是一款强大的人工智能助手,旨在帮助你轻松创建引人入胜的内容和令人印象深刻的演示。

下载

十二、sleep 、wait、yield 的区别,wait 的线程如何唤醒它?

yield()方法:使当前线程让出 CPU 占有权,但让出的时间是不可设定的。也不会释放锁资源。所有执行 yield()的线程有可能在进入到就绪状态后会被操作系统再次选中马上又被执行。
       yield() 、sleep()被调用后,都不会释放当前线程所持有的锁。
       调用 wait()方法后,会释放当前线程持有的锁,而且当前被唤醒后,会重新去竞争锁,锁竞争到后才会执行 wait 方法后面的代码。
       Wait 通常被用于线程间交互,sleep 通常被用于暂停执行,yield()方法使当前线程让出 CPU 占有权。
       wait 的线程使用 notify/notifyAll()进行唤醒。

十三、sleep 是可中断的么?

sleep 本身就支持中断,如果线程在 sleep 期间被中断,则会抛出一个中断异常。

十四、线程生命周期。

Java 中线程的状态分为 6 种:

  1. 初始(NEW):新创建了一个线程对象,但还没有调用 start()方法。

  2. 运行(RUNNABLE):Java 线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。 线程对象创建后,其他线程(比如 main 线程)调用了该对象的 start()方法。 该状态的线程位于可运行线程池中,等待被线程调度选中,获取 CPU 的使用权, 此时处于就绪状态(ready)。就绪状态的线程在获得 CPU 时间片后变为运行中 状态(running)。

  3. 阻塞(BLOCKED):表示线程阻塞于锁。

  4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作 (通知或中断)。

  5. 超时等待(TIMED_WAITING):该状态不同于 WAITING,它可以在指定的时 间后自行返回。

  6. 终止(TERMINATED):表示该线程已经执行完毕。

Java线程面试题的知识点有哪些

十五、ThreadLocal 是什么?

ThreadLocal 是 Java 里一种特殊的变量。ThreadLocal 为每个线程都提供了变量的副本,使得每个线程在某一时间访问到的并非同一个对象,这样就隔离了多个线程对数据的数据共享。
       在内部实现上,每个线程内部都有一个 ThreadLocalMap,用来保存每个线程所拥有的变量副本。

十六、线程池基本原理。

在开发过程中,合理地使用线程池能够带来 3 个好处。
第一:降低资源消耗。
第二:提高响应速度。
第三:提高线程的可管理性。

  1. 如果当前运行的线程少于 corePoolSize,则创建新线程来执行任务(注意, 执行这一步骤需要获取全局锁)。

  2. 如果运行的线程等于或多于 corePoolSize,则将任务加入 BlockingQueue。

  3. 如果无法将任务加入 BlockingQueue(队列已满),则创建新的线程来处理任务。

  4. 如果创建新线程将使当前运行的线程超出 maximumPoolSize,任务将被拒绝,并调用 RejectedExecutionHandler.rejectedExecution()方法。

十七、有三个线程 T1,T2,T3,怎么确保它们按顺序执行?

可以用 join 方法实现。

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

89

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

276

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

59

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

99

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

105

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

230

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

619

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

173

2026.03.04

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.3万人学习

Java 教程
Java 教程

共578课时 | 82.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号