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

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

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

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

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

1)final 和可以保证可见性吗?

final 关键字可以确保在多线程环境下的一些可见性和内存一致性,但它不是一种通用的可见性保证机制。具体来说:

  • 对于基本数据类型final 可以确保在多线程环境下的可见性和不可变性。一旦一个 final 变量被赋予了初始值,其他线程在读取该变量时将会看到最新的值,而且该变量不可被修改。
  • 对于引用类型final 修饰的引用变量保证了引用的不可变性,即这个引用变量只能指向初始化时指定的对象,不能指向其他对象。但是,final 并不保证引用对象的状态的不可变性,即被 final 修饰的引用指向的对象的状态仍然可以改变,因此如果引用的对象是可变的,其他线程在读取该引用指向的对象时仍然可能看到旧的状态。

综上所述,final 关键字可以确保可见性和不可变性,但仅限于被修饰的变量本身,而不涉及引用对象的状态。

2)为什么需要 ThreadLocal

ThreadLocal 是一个线程封闭的变量,在多线程环境下,每个线程都拥有自己独立的 ThreadLocal 变量副本,互不干扰。主要用途包括:

  • 线程安全:通过 ThreadLocal 可以避免多线程之间共享数据时的竞态条件和同步问题,每个线程都可以独立访问自己的 ThreadLocal 变量副本,不会被其他线程修改而影响。
  • 避免参数传递:使用 ThreadLocal 可以避免在方法间频繁传递参数,特别是那些需要在多个方法中使用的参数,将这些参数放在 ThreadLocal 中可以在方法中直接访问,简化了代码逻辑。
  • 上下文隔离:在某些情况下,需要在同一个线程的多个方法中共享某些数据,但不希望将这些数据暴露给其他线程,这时可以使用 ThreadLocal 来存储这些数据,实现上下文隔离。

3)应该如何设计 ThreadLocal ?

在设计 ThreadLocal 使用时,需要考虑以下几个方面:

  • 生命周期管理:确保 ThreadLocal 变量的生命周期符合业务需求,避免内存泄漏和意外的持有时间过长。
  • 初始值设置:可以通过 initialValue() 方法或者 withInitial() 方法来设置 ThreadLocal 初始值,确保在第一次访问时能够获取到正确的值。
  • 避免过度使用:虽然 ThreadLocal 在某些场景下非常有用,但过度使用 ThreadLocal 也可能导致代码可读性下降和难以调试的问题,需要权衡使用场景。
  • 内存使用ThreadLocal 变量是存储在每个线程的 ThreadLocalMap 中的,因此需要注意内存占用问题,避免一次性存放大量数据导致内存占用过高。
  • 清理资源:在不再需要使用 ThreadLocal 变量时,需要及时清理,避免内存泄漏,可以通过调用 remove() 方法来清理 ThreadLocal 变量。

综上所述,设计 ThreadLocal 需要考虑到生命周期管理、初始值设置、避免过度使用、内存使用和清理资源等方面。

4)从源码看 ThreadLocal 的原理

ThreadLocal 的核心原理是通过 ThreadLocalMap 来实现线程本地变量的存储和访问。每个线程都有一个 ThreadLocalMap,其中的键值对是 ThreadLocal 实例作为键,线程本地变量作为值。

当调用 ThreadLocalset() 方法时,会先获取当前线程的 ThreadLocalMap,然后将 ThreadLocal 实例作为键,要存储的值作为值,存入 ThreadLocalMap 中。当调用 get() 方法时,也是先获取当前线程的 ThreadLocalMap,然后根据 ThreadLocal 实例获取对应的值。

ThreadLocal 中,使用了弱引用来解决内存泄漏的问题。具体来说,ThreadLocal 中的 ThreadLocalMap 使用了 WeakReference 来持有 ThreadLocal 对象,这样当 ThreadLocal 对象没有强引用时,垃圾回收器可以自动回收它,从而防止内存泄漏。

5)ThreadLocal 内存泄露之为什么要用弱引用

ThreadLocal 内存泄漏通常发生在 ThreadLocal 没有被清理的情况下,但线程已经结束,而 ThreadLocalMap 中的引用仍然存在,导致 ThreadLocal 无法被垃圾回收,从而造成内存泄漏。

使用弱引用可以解决这个问题,因为弱引用不会阻止对象被垃圾回收。当 ThreadLocal 对象没有强引用时,即使在 ThreadLocalMap 中还有对它的弱引用,垃圾回收器也可以回收这个 ThreadLocal 对象。这样就避免了因为线程结束而导致的 ThreadLocal 内存泄漏问题。

6)ThreadLocal 的最佳实践

在使用 ThreadLocal 时,可以遵循以下最佳实践:

  • 及时清理资源:在不再需要使用 ThreadLocal 变量时,调用 remove() 方法清理资源,避免内存泄漏。
  • 避免过度使用:虽然 ThreadLocal 在某些场景下非常有用,但过度使用可能导致代码可读性下降和难以调试的问题,需要谨慎使用。
  • 注意内存占用:ThreadLocal 变量存储在每个线程的 ThreadLocalMap 中,需要注意内存占用问题,避免一次性存放大量数据导致内存占用过高。
  • 合理使用初始化方法:可以使用 initialValue() 方法或者 withInitial() 方法来设置 ThreadLocal 初始值,确保在第一次访问时能够获取到正确的值。
  • 线程池场景下的使用:在使用线程池的情况下,需要特别小心 ThreadLocal 的使用,因为线程池中的线程复用可能导致 ThreadLocal 变量持续存在,容易引发内存泄漏,可以考虑使用 InheritableThreadLocal 来处理线程池中的线程。

综上所述,合理使用 ThreadLocal,及时清理资源,避免过度使用,可以有效地防止内存泄漏问题,并提高代码的可维护性和可读性。

7)父子线程之间如何传递数据?

在父子线程之间传递数据,可以通过以下几种方式实现:

  1. 使用 InheritableThreadLocal:InheritableThreadLocal 是 ThreadLocal 的一个子类,它可以在父线程中设置的值自动传递给子线程。这种方式适用于父子线程之间需要共享数据的场景。
  2. 使用线程池的 ThreadLocal:如果是使用线程池管理线程的情况下,可以使用线程池的 ThreadLocal 来传递数据。线程池中的线程在执行任务时会复用,可以通过设置线程池的 ThreadLocal 来传递数据给子线程。
  3. 通过参数传递:父线程可以将需要传递的数据作为参数传递给子线程的构造函数、方法或者通过其他方式传递给子线程。
  4. 使用共享变量:父线程和子线程可以通过共享变量的方式来传递数据,但需要注意线程安全性。

以上方法可以根据具体的场景和需求选择合适的方式进行父子线程之间的数据传递。

8)ThreadLocal 的缺点?

ThreadLocal 虽然有诸多优点,但也存在一些缺点:

  1. 内存泄漏:如果没有及时调用 remove() 方法清理 ThreadLocal 变量,可能会导致内存泄漏,特别是在使用线程池的情况下。
  2. 线程池场景下的问题:在使用线程池的情况下,ThreadLocal 变量可能会被复用,导致 ThreadLocal 变量持续存在,容易引发内存泄漏。
  3. 不适合共享变量:ThreadLocal 变量仅在当前线程中可见,不适合用于共享变量,如果需要多个线程之间共享数据,还是需要考虑其他方式。
  4. 上下文传递不明确:使用 ThreadLocal 变量可能会导致代码的上下文传递不明确,可读性下降。

9)应该如何针对 ThreadLocal 缺点改进

针对 ThreadLocal 的缺点,可以考虑以下改进方式:

  1. 合理管理资源:及时调用 remove() 方法清理 ThreadLocal 变量,避免内存泄漏问题。
  2. 使用线程池专用的 ThreadLocal 实现:针对线程池场景,可以使用专门针对线程池设计的 ThreadLocal 实现,如 FastThreadLocal。
  3. 避免滥用:避免在不适合的场景下滥用 ThreadLocal,考虑是否真正需要线程间隔离和独立的场景。
  4. 考虑其他数据传递方式:在需要共享数据的场景下,考虑使用其他方式传递数据,如通过参数传递、全局变量等。
  5. 加强文档和培训:加强对 ThreadLocal 使用的文档和培训,让开发人员充分了解 ThreadLocal 的使用场景、注意事项和最佳实践。

10)FastThreadLocal 的原理是?

FastThreadLocal 是一个对 ThreadLocal 的替代实现,旨在解决 ThreadLocal 在高并发场景下性能不佳的问题。其原理主要包括以下几点:

  1. 使用数组代替 Map:FastThreadLocal 使用数组来存储线程本地变量,而不是使用 HashMap。这样可以减少散列计算和冲突处理的开销。
  2. 索引代替弱引用:FastThreadLocal 使用线程索引来访问线程本地变量,而不是通过弱引用和哈希表查找。每个线程都有一个唯一的索引,可以直接通过索引来访问线程本地变量。
  3. 空间换时间:FastThreadLocal 通过空间换时间的方式来提高性能,通过预先分配足够的空间来存储线程本地变量,避免了动态扩容和哈希表的开销。
  4. 线程安全性:FastThreadLocal 通过线程索引来访问线程本地变量,保证了线程安全性,避免了多线程竞争的问题。

综上所述,FastThreadLocal 主要通过使用数组代替 Map、索引代替弱引用和空间换时间等方式来提高

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

前后端总计已经 1300+ Star,2 W+ 访问!

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

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

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

相关文章

woffice– 内部网和外部网WordPress高端资讯主题

下载地址:https://m.gx.cn/site/3046.html 完全灵活,与最新的WordPress品牌兼容 翻译语言超过15种 使用最新技术设计快速web应用程序 所有这些都以谷歌材料设计为灵感,采用易于定制的设计,给人一种优美的现代感和易于导航的用户…

ERROR 1045 (28000) Access denied for user ‘root‘@‘IP‘(using password YES/NO)

查看权限 要查看MySQL用户的权限,您可以使用SHOW GRANTS语句。这将列出用户的权限,包括授予的权限和可以授予其他用户的权限。 以下是查看当前用户权限的SQL命令: SHOW GRANTS; 如果您想查看特定用户的权限,可以使用以下命令&…

让 CloudFlare 支持 Brotli 压缩算法 11 级压缩比,更节流!

站长们应该都知道 Brotli 压缩算法吧,这是一种通用的无损压缩算法。它结合使用 LZ77 算法的一个现代变体(Lempel-Ziv 编码)、霍夫曼编码和二阶上下文建模来压缩数据,提供了与当前最佳通用压缩方法相媲美的压缩比。2015 年 9 月谷歌…

笔记-跨域方式实现原理

websocket Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后&#xff…

51-50 两万字长文解读ControlNet论文和代码,以及自定义模型训练和图片精确控制生成实验

今天咱们来看 ICCV2023 最佳论文Adding Conditional Control to Text-to-Image Diffusion Models,又称为ControlNet。提到图像生成Finetuning工程方法,有Textual inversion、DreamBooth、LoRA、T2I-Adapter以及ControlNet,其中最著名的当属Co…

Jupyter配置

一、修改Jupyter打开界面 (1)打开【Anaconda Prompt】,输入【jupyter notebook --generate-config】命令 从运行结果可知【jupyter_notebook_config.py】的位置 (2)使用【记事本】打开 找到# c.NotebookApp.noteb…

同城预约上门服务家政小程序

基于Thinkphp和原生微信小程序开发的一款同城预约、上门服务、到店核销家政系统,用户端、服务端、门店端各端相互依赖又相互独立,支持选择项目、选择服务人员、选择门店多种下单方式,支持上门服务和到店核销两种服务方式,支持自营…

瞬息全宇宙——平行宇宙终极教程,手把手教你做出百万点赞视频

最近一种叫“瞬息全宇宙”的视频火了,抖音一期视频百万赞,各个博主视频都在带瞬息全宇宙这个标签,于是就有很多朋友催我出教程了,在琢磨了几天之后,终于整出来了 教程包含了插件的安装,界面的讲解&#xff…

C语言 | Leetcode C语言题解之第80题删除有序数组中的重复项II

题目&#xff1a; 题解&#xff1a; int removeDuplicates(int* nums, int numsSize) {if (numsSize < 2) {return numsSize;}int slow 2, fast 2;while (fast < numsSize) {if (nums[slow - 2] ! nums[fast]) {nums[slow] nums[fast];slow;}fast;}return slow; }

Nginx线程池源码刨析

Nginx线程池源码刨析 相关的API int thread_mutex_create (pthread_mutex_t *mtx); int thread_mutex_destroy (pthread_mutex_t *mtx); int thread_mutex_lock (pthread_mutex_t *mtx); int thread_mutex_unlock (pthread_mutex_t *mtx); …

「PHP系列」PHP AJAX RSS 阅读器

文章目录 一、AJAX RSS 阅读器1. HTML结构 (index.html)2. PHP处理RSS (rss_fetcher.php)注意事项&#xff1a; 二、AJAX RSS 阅读器运用步骤 1: 设置HTML页面步骤 2: 编写PHP脚本 (rss_fetcher.php)步骤 3: 配置服务器步骤 4: 测试额外提示&#xff1a; 三、相关链接 一、AJAX…

python微信小程序 django+uniapp民宿房屋租赁短租系统

本课题主要基于微信小程序的民宿短租系统的设计&#xff0c;实现了在微信小程序里的民宿房屋的管理系统&#xff0c;系统将房屋信息发布&#xff0c;房屋租赁等功能集于一身&#xff0c;为热爱旅游的用户提供了多种多样的房屋租赁业务&#xff0c;同时也方便了房屋的拥有者发布…

问题解决记录 | 内存溢出

报错截图&#xff1a; 处理方式&#xff1a; 增大PDI工具的内存 打开Spoon.bat配置文件 修改配置

第六节笔记及作业----Lagent AgentLego 智能体应用搭建

关于 Agent 的相关理论 大语言模型存在一些局限性&#xff0c;比如会出现幻觉问题、有时效性问题以及可靠性问题。智能体的定义是具备感知、决策和行动能力的实体。智能体主要由感知部分、大脑部分和动作部分组成。智能体有多种类型&#xff0c;如 ReAct 类型&#xff08;侧重…

落地领域大模型应知必会 (1) :主要微调方法总览

在如今高速发展的人工智能领域&#xff0c;高效地利用大语言模型&#xff08;LLMs&#xff09;已经变得越来越重要。但是&#xff0c;利用大语言模型的方式太多了&#xff0c;如果你才刚刚开始接触它&#xff0c;可能会感到不知所措。 实质上&#xff0c;我们可以通过两种主要…

Github 2024-05-09 Go开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-09统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10Gin Web框架:高性能的Go HTTP框架 创建周期:3496 天开发语言:Go协议类型:MIT LicenseStar数量:73548 个Fork数量:7831 次关注人数…

项目经理必须要学会使用原型图工具或者别的必要工具吗

项目经理不一定必须学会使用原型图工具或其他特定技术工具&#xff0c;但熟悉和掌握一些关键工具和技术无疑会提高他们的工作效率和项目管理能力。以下是关于项目经理是否需要学习使用原型图工具或其他必要工具的几点考虑&#xff1a; 项目需求&#xff1a; 如果项目涉及产品设…

信创应用软件之国产邮箱

信创应用软件之国产邮箱 文章目录 信创应用软件之国产邮箱采用信创邮箱的必要性信创邮箱采购需求国产邮箱业务形态国产邮箱代表性品牌CoremailRichmail安宁eyouUMail拓波 邮件安全的发展阶段 采用信创邮箱的必要性 邮箱是天然的数据存储空间&#xff0c;党政和央国企客户在使用…

软件3班20240513

java.util.PropertyResourceBundle4554617c package com.yanyu;import java.sql.*; import java.util.ResourceBundle;public class JDBCTest01 {public static void main(String[] args) throws SQLException { // 获取属性配置文件ResourceBundle bundle Res…

高效文件管理:一键批量修改文件名,并统一转换为大写扩展名

在现代社会中&#xff0c;无论是个人还是企业&#xff0c;我们都需要处理大量的文件。有效的文件管理不仅能提高我们的工作效率&#xff0c;还能确保数据的完整性和安全性。其中&#xff0c;批量修改文件名和扩展名是一种常用的文件管理方式&#xff0c;本文将详细介绍云炫文件…