ThreadLocal使用总结
一、ThreadLocal基本使用
1.1使用场景
不同的线程对全局变量进行修改,使用ThreadLocal后会为每个线程创建一个副本,而不会影响其他线程的副本,确保了线程的安全
private static ThreadLocal<Integer> localvariable=ThreadLocal.withInitial(()->1);
public static void main(String[] args) {
Thread threadOne=new Thread(new Runnable() {
@Override
public void run() {
Integer integer = localvariable.get();
localvariable.set(++integer);
System.out.println("线程1: "+localvariable.get());
}
});
Thread threadTwo=new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程2: "+localvariable.get());
}
});
System.out.println("主线程: "+localvariable.get());
threadOne.start();
threadTwo.start();
}
运行结果:
主线程: 1
线程1: 2
线程2: 1
线程1的修改没有影响到线程2的读取,保证了线程的安全
场景二
类似于全局变量,但是不想被多个线程进行共享
private static Integer count=0;
private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
for(int i=0;i<10;i++){
Runnable runnable = new Runnable(){
@Override
public void run() {
System.out.println(count);
}
};
fixedThreadPool.execute(runnable);
}
count++;
}
像如上代码,本来是想所有线程都输出初始的count,当主线程累加后,剩下的线程输出的值就变成了1
以上代码执行的结果:
0
0
0
0
1
1
1
1
1
1
那么我们可以用ThreadLocal将原始的全局变量进行保存然后传参给其他的线程,这样就获取的是原始的全局变量
private static Integer count=0;
private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
private static ThreadLocal<Integer> local=new ThreadLocal();
public static void main(String[] args) {
local.set(count);
for(int i=0;i<10;i++){
Integer localCount = local.get();
Runnable runnable = new Runnable(){
@Override
public void run() {
System.out.println(localCount);
}
};
fixedThreadPool.execute(runnable);
}
count++;
}
0
0
0
0
0
0
0
0
0
0
1.2 原理分析
threadLocals = null;
inheritableThreadLocals = null;
Thread类中有一个threadLocals和一个inheritableThreadLocals,他们都是ThreadLocalMap 类型的变量,默认都为null
当第一次调用set方法的时候创建
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
将每个线程的本地变量存放在threadLocals变量中,如果调用线程一直不终止,那么这个本地变量会一直存放在调用线程的ThreadLocals变量里面,所以当不使用本地变量是可以通过调用ThreadLocal变量的remove方法,从当前线程的threadLocals
里面删除该本地变量。
ThreadLocal 是JDK 包提供的,它提供了线程本地变量,也就是如果你创建了一个
ThreadLocal 变量,那么访问这个变量的每个线程都会有这个变量的一个本地副本。当多
个线程操作这个变量时,实际操作的是自己本地内存里面的变量,从而避免了线程安全问
题
ThreadLocal使用总结的更多相关文章
- ThreadLocal简单理解
在java开源项目的代码中看到一个类里ThreadLocal的属性: private static ThreadLocal<Boolean> clientMode = new Thread ...
- Android线程管理之ThreadLocal理解及应用场景
前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...
- Threadlocal使用Case
Threadlocal能够为每个线程分配一份单独的副本,使的线程与线程之间能够独立的访问各自副本.Threadlocal 内部维护一个Map,key为线程的名字,value为对应操作的副本. /** ...
- 多线程映射工具——ThreadLocal
ThreadLocal相当于一个Map<Thread, T>,各线程使用自己的线程对象Thread.currentThread()作为键存取数据,但ThreadLocal实际上是一个包装了 ...
- ThreadLocal 工作原理、部分源码分析
1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...
- ThreadLocal<T>的是否有设计问题
一.吐槽 ThreadLocal<T>明显是.NET从JAVA中来的一个概念,但是这种设计是否出现了问题. 很明显,在JAVA中threadLocal直接是Thread的成员,当然随着th ...
- 理解ThreadLocal —— 一个map的key
作用: 当工作于多线程中的对象使用ThreadLocal维护变量时,threadLocal为每个使用该变量的线程分配一个独立的变量副本. 接口方法: protected T initialValue( ...
- JavaSe:ThreadLocal
JDK中有一个ThreadLocal类,使用很方便,但是却很容易出现问题.究其原因, 就是对ThreadLocal理解不到位.最近项目中,出现了内存泄漏的问题.其中就有同事在使用ThreadLocal ...
- 0041 Java学习笔记-多线程-线程池、ForkJoinPool、ThreadLocal
什么是线程池 创建线程,因为涉及到跟操作系统交互,比较耗费资源.如果要创建大量的线程,而每个线程的生存期又很短,这时候就应该使用线程池了,就像数据库的连接池一样,预先开启一定数量的线程,有任务了就将任 ...
- ThreadLocal 源码剖析
ThreadLocal是Java语言提供的用于支持线程局部变量的类.所谓的线程局部变量,就是仅仅只能被本线程访问,不能在线程之间进行共享访问的变量(每个线程一个拷贝).在各个Java web的各种框架 ...
随机推荐
- Springboot使用EasyExcel(仅限自己收藏)
pom文件依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel< ...
- 通过RayFire为图形添加二次破碎效果
在完成3D建模之后,RayFire能帮助用户制作多种类型的破碎效果,如均匀碎片.放射状碎片.木碎等效果.另外,用户还可以利用RayFire的碎片选取功能,为图形进行二次破碎,以达到增加局部碎片的效果. ...
- mac中怎么完成移动硬盘分区这个操作
移动硬盘在出厂时只有一个区,不方便我们存储和查阅文件,移动硬盘分区可以防止硬盘发生错误,以免造成资料丢失,也可以防止产生无用文件. 移动硬盘基本上都是用Windows系统进行分区的,但是现在很多人使用 ...
- mathtype样式系统使用技巧-通过样式定义来更改方程中的字体
本教程中,我们主要介绍MathType Desktop的样式系统.演示如何通过更改样式定义来更改方程中的字体.通过样式可以快速轻松地实现我们所需的公式格式,并统一所有公式的样式. 我们以如下公式来作为 ...
- LeetCode周赛#204 题解
1566. 重复至少 K 次且长度为 M 的模式 #模拟 题目链接 题意 给定正整数数组 arr,请你找出一个长度为 m 且在数组中至少重复 k 次的模式. 模式 是由一个或多个值组成的子数组(连续的 ...
- Java基础教程——转换流
转换流 通常,Window默认的编码方式是GBK,Java项目一般建议设为UTF-8编码.这时候读取文件可能出现乱码.事实上实际应用中编码格式不匹配的场景非常多. 转换流可以指定编码方式,用于解决乱码 ...
- 关于热力图的loss的一点感想
网络的输出的热力图和gt相减的差矩阵,求其最大特征值的平方作为loss. 若图像h w不相等,可以使用奇异值代替特征值.奇异值往往对应着矩阵中隐含的重要信息,且重要性和奇异值大小正相关.每个矩阵A都可 ...
- Linux无法新增用户
1.查看当前用户是否有权限创建用户 2.磁盘空间不足,vi打开/etc/passwd 报: E297: Write error in swap file"adduser.sh" 1 ...
- linux scp 命令使用
1.scp命令使用 linux 把文件复制到另一台服务器上 复制文件 scp file_name user_name@remote_ip:file_path 复制文件夹 scp -r file_nam ...
- 老猿学5G:多量纲计费与QoS的QCI、5QI、ARP、GBR和MBR
☞ ░ 前往老猿Python博文目录 ░ 一.多量纲计费 多量纲计费是与传统的计费模式相区别的一种计费模式,传统的计费基本上都是通过使用量.使用时长或包固定时长等方式计费,而多量纲计费是指在考虑以上方 ...