当前位置:网站首页>ThreadLocal变量使用及原理
ThreadLocal变量使用及原理
2022-07-17 13:44:00 【Mr清奇】
使用场景
单例模式中,对于某个成员变量,如果需要每个线程独占一份副本,可以使用ThreadLocal进行修饰。
例如在spring中,bean的默认作用域为SINGLTON,即单例。如果单例的bean中有实例变量,则此变量是线程不安全的。一个解决办法就是用ThreadLocal来修饰。
使用方法
应用代码
public class SingleClass {
// ThreadLocal存储的变量类型可以使用泛型指定,不指定时默认为Object
// 以下代码等同于public static ThreadLocal<Object> t1 = new ThreadLocal();
public static ThreadLocal t1 = new ThreadLocal();
// 获取ThreadLocal变量值
public static Object getT1() {
return t1.get();
}
//设置ThreadLocal变量值
public static void setT1(Object tValue) {
t1.set(tValue);
}
}
原理
ThreadLocal变量实际是存放在Thread线程对象的一个实例变量中(此变量的可见范围为Package,对外部包不可见),类型为Map。调用ThreadLocal变量Set方法设置值的时候,实际上是向Map中添加了一个Entry,Entry的key就是当前变量,Value为需要set的值,以此可以保证每个线程独占自己的副本。
逻辑原理图如下:
默认初始值
ThreadLocal变量如果未进行set,直接get,会得到null值。如需对ThreadLocal添加默认初始值,可以自定义ThreadLocal类,继承原ThreadLocal后,重写initialValue()方法即可。
public class MyThreadLocal extends ThreadLocal {
@Override
protected Object initialValue() {
// 初始值为当前时间字符串
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
}
在应用代码中通过自定义的类来定义ThreadLocal变量:
public class SingleClass {
public static ThreadLocal t1 = new MyThreadLocal();
}
继承父线程设置的值
子线程如果需要获取父线程中设置的值,可以使用InheritableThreadLocal类。
public class SingleClass {
public static ThreadLocal t1 = new InheritableThreadLocal();
}
测试类
public class ThreadA extends Thread {
@Override
public void run() {
System.out.println(SingleClass.t1.get());
SingleClass.t1.set("child-value");
System.out.println(SingleClass.t1.get());
}
}
public class TestThreadLocal {
public static void main(String[] args) {
SingleClass.t1.set("main-value");
ThreadA ta = new ThreadA();
ta.start();
}
}
执行结果:
main-value
child-value
边栏推荐
- 过拟合与欠拟合
- 今日睡眠质量记录79分
- LeetCode 745. 前缀和后缀搜索
- 发明闪存能赚多少钱?这是一个日本的狗血故事
- Custom complex logic verification during adding and modifying -2022 new project
- Pytorch.nn实现多层感知机
- LeetCode 2335. Minimum total time required to fill the cup
- 手机键盘(模拟题)
- Pytoch framework learning record 1 cifar-10 classification
- Use testeract JS offline recognition picture text record
猜你喜欢
Common collection properties
论文笔记:Mind the Gap An Experimental Evaluation of Imputation ofMissing Values Techniques in TimeSeries
使用tesseract.js-offline识别图片文字记录
The difference between journal log and oplog log
如何在 RHEL 9 中更改和重置忘记的root密码
NVIDIA uses AI to design GPU: the latest H100 has been used, which reduces the chip area by 25% compared with traditional EDA
LeetCode 2319. Judge whether the matrix is an X matrix
剑指 Offer II 041. 滑动窗口的平均值
LeetCode 2325. Decrypt message (map)
[in vivado middle note ILA IP core]
随机推荐
Google Earth Engine——Hansen Global Forest Change v1.8 (2000-2020) 森林覆盖度和森林损失量数据集
Unity3d 模型中心点的转换(源代码)
Use testeract JS offline recognition picture text record
UE4 understanding of animation blueprint
今日睡眠质量记录79分
修改Jupyter默认路径看这篇!
早期单片机加密的一些方法 【评论区领取资料】
英伟达用AI设计GPU:最新H100已经用上,比传统EDA减少25%芯片面积
[Huawei cloud IOT] reading notes, "Internet of things: core technology and security of the Internet of things", Chapter 3 (2)
Efficient space-based computing technology for satellite communication in 6g
【手写数字识别】基于Lenet网络实现手写数字识别附matlab代码
[LeetCode周赛复盘] 第 302 场周赛20220717
Openfoam heat flow boundary condition
Journal日志与oplog日志的区别
How to build dashboard and knowledge base in double chain note taking software? Take the embedded widget library notionpet as an example
Maximal semi connected subgraph (tarjan contraction + topological ordering + DP longest chain)
input number 纯数字输入 限制长度 限制 最大值
Satellite network capacity improvement method based on network coding
LeetCode 2331. 计算布尔二叉树的值(树的遍历)
2022/7/14