Java面试题:请谈谈对ThreadLocal的理解?
ThreadLocal是一种特殊的变量存储机制,它提供了一种方式,可以在每个线程中保存数据,而不会受到其他线程的影响。这种机制在多线程编程中非常有用,因为它允许每个线程拥有自己的数据副本,从而避免了数据竞争和线程之间的干扰,以空间换时间。
在Java中,ThreadLocal的实现主要涉及到三个类:ThreadLocal、ThreadLocalMap和WeakReference。ThreadLocal类是核心类,用于保存线程局部变量,并提供相应的访问方法。ThreadLocalMap是一个哈希表,用于存储每个线程的本地变量。WeakReference类是一个辅助类,用于处理弱引用问题。
下图可以增强理解:

由上图我们可以看到ThreadLocal的内部实现包括以下几个步骤:
创建一个ThreadLocalMap对象,用于存储每个线程的本地变量。
在ThreadLocal对象中保存一个WeakReference对象,用于存储本地变量的值。这个WeakReference对象本身并不保存实际的值,而是保存了一个指向本地变量值的引用。
当访问本地变量时,如果本地变量已经存在,则直接使用已有的变量值;否则,创建一个新的本地变量并保存到ThreadLocalMap中。
下面是一个使用ThreadLocal的简单案例:
假设有一个计数器类CountingThreadLocal,它使用ThreadLocal保存计数器的值。在主线程中创建多个子线程,每个子线程都从主线程读取数据,修改计数器的值,设置到自己的本地内存里面,并打印结果。
一张示意图如下:

代码实现如下:
public class CountingThreadLocal {
private static final ThreadLocal<Integer> counter = new ThreadLocal<Integer>(){
@Override
protected Integer initialValue() {
return 0;
}
};
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
int count = counter.get(); // 获取当前线程的计数器值
count++; // 修改计数器值
System.out.println("Thread " + Thread.currentThread().getName() + " counts: " + count);
counter.set(count); // 将修改后的计数器值保存回ThreadLocal中
}).start();
}
}
}
输出结果如下:
Thread Thread-0 counts: 1
Thread Thread-4 counts: 1
Thread Thread-3 counts: 1
Thread Thread-2 counts: 1
Thread Thread-1 counts: 1
Thread Thread-7 counts: 1
Thread Thread-6 counts: 1
Thread Thread-5 counts: 1
Thread Thread-9 counts: 1
Thread Thread-8 counts: 1
在上述代码中,我们使用ThreadLocal保存了一个Integer类型的计数器值。在主线程中创建多个子线程时,每个子线程都会获取当前线程的计数器值并进行修改。由于使用了ThreadLocal机制,每个线程都有自己的计数器副本,因此不会受到其他线程的影响。最终输出的结果将展示每个线程的计数器值。
最后我们总结一下:
- ThreadLocal的实现涉及到三个类:ThreadLocal、ThreadLocalMap和WeakReference。
- ThreadLocal是一种非常有用的线程局部变量存储机制,它允许每个线程拥有自己的数据副本,从而避免了数据竞争和线程之间的干扰。
Java面试题:请谈谈对ThreadLocal的理解?的更多相关文章
- JAVA面试题 请谈谈你对Sychronized关键字的理解?
面试官:sychronized关键字有哪些特性? 应聘者: 可以用来修饰方法; 可以用来修饰代码块; 可以用来修饰静态方法; 可以保证线程安全; 支持锁的重入; sychronized使用不当导致死锁 ...
- Java面试题必备知识之ThreadLocal
老套路,先列举下关于ThreadLocal常见的疑问,希望可以通过这篇学习笔记来解决这几个问题: ThreadLocal是用来解决什么问题的? 如何使用ThreadLocal? ThreadLocal ...
- Java面试题之谈谈你对Struts的理解
1. struts是一个按MVC模式设计的Web层框架,其实它就是一个大大的servlet,这个Servlet名为ActionServlet,或是ActionServlet的子类.我们可以在web.x ...
- java面试题之什么是ThreadLocal?底层如何实现的?
ThreadLocal是一个解决线程并发问题的一个类,用于创建线程的本地变量,我们知道一个对象的所有线程会共享它的全局变量,所以这些变量不是线程安全的,我们可以使用同步技术.但是当我们不想使用同步的时 ...
- Java面试题之谈谈reactor模型
reactor是什么? 事件驱动 可以处理一个或多个输入源 通过Service Handle同步的将输入事件采用多路复用分发给相应的Request Handler(一个或多个)处理 具体可参考:htt ...
- java面试题之谈谈你对java的理解
平台无关性:一处编译到处运行 GC:不用像c++那样手动释放堆内容 语言特性:泛型.反射.lamda表达式 面向对象:封装.继承.多态 类库:集合.并发库.网络库.IO库 异常处理
- java面试题——对于多态你是怎么理解的呢?不一样的角度,带你重新看java
java面试的时候经常会被问到一个问题,那就是java三大特性:继承,封装和多态.那么这三者的含义究竟是什么你真的清楚吗?我看网上大多都是人云亦云.所以我想把我的想法记录下来供大家参考-今天先聊一个, ...
- Java 面试题 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- java面试题(杨晓峰)---第三讲谈谈final、finally、finalize有什么不同?
java语言有很多看起来相似,但用途却完全不相同的语言要素,这些内容往往容易成为面试官考察你知识掌握程度的切入点. 今天我要问你一个基础的java经典题目,谈谈final.finally.finali ...
- Java面试题之基础篇概览
Java面试题之基础篇概览 1.一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,且public的类名必须与文件名相一致. 2.Ja ...
随机推荐
- Java处理子父级菜单的方式二
处理存在子父级关系的数据是写代码的过程中常见的操作,前面讲解过使用递归的方法来做, 可以参考这篇博客 https://www.cnblogs.com/yilangcode/p/16831867.htm ...
- 6 定时器 &中断管理&资源管理
生成函数 周期,多久触发一次定时器(从定时器启动开始计算) 触发什么呢? 回调函数被调用,被谁调用呢 1,tick中断去调用timer函数 Linux中使用这个 (定时器回调函数若执行时间过长, ...
- python中往json中添加文件的方法
一 前言: python中常用的一种方式,这里给大家列出来一下. 二 实例 比如,最简单的一个json文件 test_json = { "a": 1, "b": ...
- BigDecimal类处理高精度计算
BigDecimal类处理高精度计算 Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数,但 ...
- Kotlin 集合对象的单条件和多条件排序
原文: Kotlin 集合对象的单条件和多条件排序 - Stars-One的杂货小窝 本文不是太难的东西,因为sortedWith之前没怎么用过,所以就记录下 平常开发经常使用到List,Map等数据 ...
- Android 开发Day10
这是main里面的所有代码,按版本修改过 AndroidManifest.xml <?xml version="1.0" encoding="utf-8" ...
- JQ实现音乐插件并自动播放
这里分享我最近写出来的一个小东西,基于jq的音乐播放器,可以嵌套到网站 效果截图: 具体首页代码如下: <!DOCTYPE html> <html> <head> ...
- FFmpeg开发笔记(七)欧拉系统编译安装FFmpeg
FFmpeg支持Linux.macOS.Windows.Android等操作系统,其中Linux系列包括Ubuntu.Debian.Mint.CentOS.RHEL.Fedora等分支.FFmpeg官 ...
- FFmpeg开发笔记(六)如何访问Github下载FFmpeg源码
学习FFmpeg的时候,经常要到GitHub下载各种开源代码,比如FFmpeg的源码页面位于https://github.com/FFmpeg/FFmpeg.然而国内访问GitHub很不稳定,经常打 ...
- 从零开始写 Docker(九)---实现 mydocker ps 查看运行中的容器
本文为从零开始写 Docker 系列第九篇,实现类似 docker ps 的功能,使得我们能够查询到后台运行中的所有容器. 完整代码见:https://github.com/lixd/mydocker ...