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的各种框架 ...
随机推荐
- 面试半年,凭借这份JVM面试题,我终于拿到了字节跳动的offer!
内存区域 虚拟机栈生命周期与线程相同,描述的是Java 方法执行的内存模型,每个方法在执行的时候都会创建一个栈帧,用于存取局部变量表.操作数栈.动态链接.方法出口等信息本地方法栈与虚拟机栈作用相似,只 ...
- Elements-of-Python01_Input/Output
(内容包括输入input,输出print,注释comment,预测类型转换eval,命名与赋值Name & Bestow) 输入Input 和 输出Print Python中利用input() ...
- Camtasia Studio,一款好用到爆炸的视频录制软件
目前网络中有很多视频录制软件,各有特色,经过亲测今天小编为大家推荐一款比较好的视频录制软件就是Camtasia Studio软件,Camtasia支持视频的高清录制以及视频的导入导出,而且最支持导出的 ...
- Linux 学习笔记01丨Ubuntu系统安装、配置及软件教程集合
1. Ubuntu系统安装 Windows10安装ubuntu18.04双系统教程 Ubuntu 20.04.1 镜像下载 软碟通 机械革命进入BIOS模式 要按F2,注意将Boot Option中将 ...
- Java蓝桥杯——递归练习题:走台阶(偶数版)
递归练习题:走台阶(偶数版) 小明刚刚看完电影<第39级台阶>.离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级! 站在台阶前,他突然又想着一个问题: 如果我每一步只能迈上1个或2个 ...
- 如何实现一个简易版的 Spring - 如何实现 Setter 注入
前言 之前在 上篇 提到过会实现一个简易版的 IoC 和 AOP,今天它终于来了...相信对于使用 Java 开发语言的朋友们都使用过或者听说过 Spring 这个开发框架,绝大部分的企业级开发中都离 ...
- 交换机Access、Trunk和Hybrid 接口类型及区别
交换机接口的类型可以是 Access.Trunk和Hybrid. Access类型的接口仅属于一个VLAN,只能接收.转发相应VLAN的帧: Trunk类型接口则默认属于所有VLAN,任何 Tagge ...
- Oracle11gR2 RAC voting disk error
故障现象:2+3节点配置,alert日志中提示vote盘错误,集群无法拉起来. 分析过程:Oracle 11g RAC依据OLR,OCR,VOTE磁盘进行节点信息注册,维护集群状态以及完成选举投票.其 ...
- HTML-webstorm添加快捷键
快速输入标签: 先输入标签p,按Tab键变成<p></p>,光标会在标签中间 输入内容后按end键 快速复制粘贴光标所在的一整行内容Ctrl+D 快速删除光标所在的行 Ctrl ...
- for循环与while循环
1.两中循环的语法结构 for循环结构: for(表达式1;表达式2;表达式3) { 执行语句; } while循环结构: while(表达式1) { 执行语句; } 2.两者区别: 应用场景:由于f ...