早在Java
1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序时提供了一种新的选择。使用
这个工具类可以很简洁地编写出优美的多线程程序,虽然ThreadLocal非常有用,但是似乎现在了解它、使用它的朋友还不多。
ThreadLocal是什么
ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread
local
variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,
就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每
一个线程都完全拥有该变量。线程局部变量并不是Java的新发明,在其它的一些语言编译器实现(如IBM XL
FORTRAN)中,它在语言的层次提供了直接的支持。因为Java中没有提供在语言层次的直接支持,而是提供了一个ThreadLocal的类来提供支
持,所以,在Java中编写线程局部变量的代码相对比较笨拙,这也许是线程局部变量没有在Java中得到很好的普及的一个原因吧。
ThreadLocal的设计
首先看看ThreadLocal的接口:
Object get() ; // 返回当前线程的线程局部变量副本 protected Object initialValue(); //
返回该线程局部变量的当前线程的初始值void set(Object value); // 设置当前线程的线程局部变量副本的值
ThreadLocal有3个方法,其中值得注意的是initialValue(),该方法是一个protected的方法,显然是为了子类重写而特意实
现的。该方法返回当前线程在该线程局部变量的初始值,这个方法是一个延迟调用方法,在一个线程第1次调用get()或者set(Object)时才执行,
并且仅执行1次。ThreadLocal中的确实实现直接返回一个null:
protected Object initialValue() { return null; }
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。比如下面的示例实现:
public class ThreadLocal
{
private Map values = Collections.synchronizedMap(new HashMap());
public Object get()
{
Thread curThread = Thread.currentThread();
Object o = values.get(curThread);
if (o == null && !values.containsKey(curThread))
{
o = initialValue();
values.put(curThread, o);
}
return o;
}
public void set(Object newValue)
{
values.put(Thread.currentThread(), newValue);
}
public Object initialValue()
{
return null;
}
}
当然,这并不是一个工业强度的实现,但JDK中的ThreadLocal的实现总体思路也类似于此。
ThreadLocal的使用
如果希望线程局部变量初始化其它值,那么需要自己实现ThreadLocal的子类并重写该方法,通常使用一个内部匿名类对ThreadLocal进行子类化,比如下面的例子,SerialNum类为每一个类分配一个序号:
public class SerialNum
{
// The next serial number to be assigned
private static int nextSerialNum = 0;
private static ThreadLocal serialNum = new ThreadLocal()
{
protected synchronized Object initialValue()
{
return new Integer(nextSerialNum++);
}
};
public static int get()
{
return ((Integer) (serialNum.get())).intValue();
}
}
SerialNum类的使用将非常地简单,因为get()方法是static的,所以在需要获取当前线程的序号时,简单地调用:
int serial = SerialNum.get();
即可。
在线程是活动的并且ThreadLocal对象是可访问的时,该线程就持有一个到该线程局部变量副本的隐含引用,当该线程运行结束后,该线程拥有的所以线程局部变量的副本都将失效,并等待垃圾收集器收集。
ThreadLocal与其它同步机制的比较
ThreadLocal和其它同步机制相比有什么优势呢?ThreadLocal和其它所有的同步机制都是为了解决多线程中的对同一变量的访问冲突,在
普通的同步机制中,是通过对象加锁来实现多个线程对同一变量的安全访问的。这时该变量是多个线程共享的,使用这种同步机制需要很细致地分析在什么时候对变
量进行读写,什么时候需要锁定某个对象,什么时候释放该对象的锁等等很多。所有这些都是因为多个线程共享了资源造成的。ThreadLocal就从另一个
角度来解决多线程的并发访问,ThreadLocal会为每一个线程维护一个和该线程绑定的变量的副本,从而隔离了多个线程的数据,每一个线程都拥有自己
的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的整个变量封装进
ThreadLocal,或者把该对象的特定于线程的状态封装进ThreadLocal。
由于ThreadLocal中可以持有任何
类型的对象,所以使用ThreadLocal
get当前线程的值是需要进行强制类型转换。但随着新的Java版本(1.5)将模版的引入,新的支持模版参数的
ThreadLocal<T>类将从中受益。也可以减少强制类型转换,并将一些错误检查提前到了编译期,将一定程度地简化
ThreadLocal的使用。
总结
当然ThreadLocal并不能替代同步机制,两者面向的问题领域不同。
同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信的有效方式;而ThreadLocal是隔离多个线程的数据共享,从根本上
就不在多个线程之间共享资源(变量),这样当然不需要对多个线程进行同步了。所以,如果你需要进行多个线程之间进行通信,则使用同步机制;如果需要隔离多
个线程之间的共享冲突,可以使用ThreadLocal,这将极大地简化你的程序,使程序更加易读、简洁。
相关推荐
小程序强制更新避坑指南:手把手教你实现无缝升级
本文详细解析小程序强制更新的实现方法,重点介绍wx.getUpdateManager API的使用技巧,帮助开发者规避冷热启动机制下的版本管理陷阱。通过实战案例展示如何设计多级更新提示策略,确保用户无缝升级,提升小程序版本更新率。
ThreadLocal介绍
一、概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是 threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量 (ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一
前端埋点的实践
1、前言 开始正文前先介绍一下埋点的概念~,(熟悉的朋友可以略过) 前端埋点: 是一种手段,它的目的是上报相关行为数据,相关人员以数据为依据来分析产品在用户端的使用情况,根据分析出来的结果辅助产品优化、迭代。 BI:商业智能,公司内部做数据分析相关的部门。 2、背景 在流量红利逐渐消失的现在,数据的采集、分析和精细化的运营显得更加重要,所以埋点的需求在互联网产品中是很常见的,目的上面也提到了。我们的追求就是又快又好的做好埋点工作,但是现实却不那么美好;目前我们团队在前端埋点方面存在一些痛点: 在构造埋点字段
ThreadLocal介绍及使用
ThreadLocal可以使每个线程保存自己的一些私有数据,起到线程隔离的作用。打个比方,可以将其比喻成大型超市里的公共储物柜,每个人都可以使用,但是储物柜又分为好多小箱子来保证每个顾客有属于自己的存储空间,只能存取自己的物品。 下面来看看ThreadLocal的使用。 1.ThreadLocal.get()和Thr...
C#开发医学影像胶片打印系统(一):万能花式布局的实现思路
本篇文章将介绍开发医学影像胶片打印系统(printscu模式)遇到不规则排版时的一种思路,一般来讲,医院打印胶片时都是整张胶片打印,但有时需要将多个病人或一个病人的多个检查打印在同一张胶片上,这时候就需要不规则排版来满足打印需求,使胶片利用率最大化。
模拟IC设计笔记:拆解一个经典的时钟占空比校正(DCC)电路模块,从理论到SPICE仿真
本文深入解析了时钟占空比校正(DCC)电路在模拟IC设计中的关键作用,特别是在高速ADC应用中。通过晶体管级拆解,详细介绍了基于电荷泵和积分器的模拟反馈型DCC电路设计,包括占空比检测、误差放大与校正执行单元的实现。文章还提供了SPICE仿真验证方法,确保电路在100MHz时钟下的稳定性和性能。
ThreadLocal--ThreadLocal介绍
摘要:ThreadLocal是Java提供的线程本地变量机制,每个线程独立维护变量副本,用于上下文传递、线程安全对象存储等场景。其核心实现依赖ThreadLocalMap,采用弱引用key防止内存泄漏。使用时需注意:1)线程池场景必须手动remove();2)子线程继承需用InheritableThreadLocal。典型应用包括用户会话管理、SimpleDateFormat线程安全封装等。关键点在于理解ThreadLocalMap的弱引用机制和及时清理,避免内存泄漏风险。(148字)
基于机器学习的电视剧类型点击量数据分析研究
1. 背景介绍 1.1 流媒体平台的兴起与电视剧市场的繁荣 近年来,随着互联网技术的飞速发展,流媒体平台如Netflix、Disney+、腾讯视频等迅速崛起,成为人们观看影视内容的主要渠道。电视剧作为流媒体平台上的重要内容类型,其点击量数据蕴含着丰富的用户偏好和市场趋势信息。
ThreadLocal介绍和使用
ThreadLocal介绍和使用
bevformer详解(3): 逐行代码讲解
在这篇文章中,我们将从BEVFormer算法代码入手,深入探究BEV转换的流程。BEVFormer是一种基于Transformer的BEV转换模型,其核心思想是利用自注意力机制和交叉注意力机制,从,并通过Object Query与BEV特征的交互,完成3D目标检测和地图分割等任务。https://developer.baidu.com/article/details/3224715bevformer的网络结构由三部分组成, 模型结构所示,其中的是部分,对于的是的结构,对于部分,沿用的中的decoder部分,
【stata基础代码大全 】 可独立完成一篇实证
用stata打开,直接替换自己需要的变量就行,小白友好❗️❗️❗️。八、八.中介效应检验:路径分析(三种方法)第二种方法即Sobel-Goodman检验。*(7)Winsor处理,剔除异常值。六、内生性问题解决方法(附具体模型)其三,工具变量:两阶段最小二乘。第三种方法即Bootstrap检验。二、Stata中数据的基本处理。*(5)生成行业、年度虚拟变量。PSM1————近邻匹配。七、调节效应检验:机制分析。*(2)剔除数据中的样本。*(4)给变量添加标签。*(3)生成新的变量。*(6)基本数据匹配。
threadLocal介绍
早在JDK 1.2 的版本中就提供java.lang.ThreadLocal ,ThreadLocal 为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal 很容易让人望文生义,想当然地认为是一个“ 本地线程” 。其实,ThreadLocal 并不是一个Thread ,而是Thread 的局部变量,也许把它...
ET2012新版免狗免安装绿色软件
ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,
ThreadLocal 简单介绍
ThreadLocal 简单介绍
汉书HE8,好用的汇编代码编写工具
汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大
jre9下载 jdk9
(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】
Android开发——ThreadLocal功能介绍
ThreadLocal适用于某些数据以线程为作用域并且不同线程具有不同数据副本的场景。 比如对于Handler来说,它需要获取当前线程的Looper,很显然Looper的作用域就是线程并且不同线程具有不同的Looper,这个时候通过ThreadLocal就可以轻松实现Looper在线程中的存取。 ThreadLocal的另一个使用场景是复杂逻辑下的对象传递。 比如监听器的传递,有时一个...
Outlook Express 6 (OE6) for Win7/Win8/Win10
英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。
介绍threadlocal
线程复用:在使用线程池时,线程可能会被复用,这可能会导致 ThreadLocal 的值被错误地共享。- 数据隔离:通过 ThreadLocal 存储的数据是线程隔离的,即每个线程只能访问和修改自己的数据副本。- 日志记录:每个线程可能会产生不同的日志信息,使用 ThreadLocal 可以避免日志信息的混淆。在这个示例中,每个线程都会获取和更新自己的 ThreadLocal 变量副本,而不会影响其他线程的值。- 线程局部变量:每个线程可以访问自己的 ThreadLocal 变量,而不会与其他线程冲突。
ThreadLocal基本介绍
ThreadLocal是Java中的一个线程本地变量,它提供了一种在多线程环境下保持变量的副本,每个线程都可以独立地修改自己的副本,而不会影响其他线程的副本。在每个线程Thread内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,value为变量副本(即T类型的变量)。
280



被折叠的 条评论
为什么被折叠?



