ThreadLocal基础

ThreadLocal类可以让每个线程绑定自己的值,它就像一个全局存放数据的盒子,盒子中可以存放每个线程的私有数据。

ThreadLocal类只有一个无参的构造函数,因此实例化ThreadLocal的方法为: new ThreadLocal<T>();

threadLocal.get()方法,取当前线程存放在ThreadLocal里的数据;

threadLocal.set(T value)方法,设置当前线程在ThreadLocal里的数据;

threadLocal.remove()方法,移除当前线程在ThreadLocal里的数据;

threadLocal.initialValue(),返回当前线程在ThreadLocal里的初始值。

类InheritableThreadLocal可以在子线程中取得父线程继承下来的值:在创建子线程时,子线程会接收所有可继承的线程局部变量的初始值,以获得父线程所具有的值。通常,子线程的值与父线程的值是一致的;但是,通过重写这个类中的 childValue 方法,子线程的值可以作为父线程值的一个任意函数。

ThreadLocal源码分析

首先看ThreadLocal类的set方法:

public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);
}ThreadLocalMap getMap(Thread t) {return t.threadLocals;
}void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);
}

可以看到它首先获取当前线程对象,然后获取线程对象的threadLocals属性,如果threadLocals为null,就新建一个ThreadLocalMap对象赋值给它,如果不为null,则直接往其上塞值。由此我们可以看到,ThreadLocal本身并不存储数据,数据存储在Thread对象上面。Thread的threadLocals属性是一个ThreadLocal.ThreadLocalMap类型的非静态属性,ThreadLocalMap的实现如下:

static class ThreadLocalMap {static class Entry extends WeakReference<ThreadLocal<?>> {/** The value associated with this ThreadLocal. */Object value;Entry(ThreadLocal<?> k, Object v) {super(k);value = v;}}...

可以看到ThreadLocalMap的Entry继承了WeakReference,它使用ThreadLocal对象作为key。

再来看ThreadLocal类的get方法:

public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}

同样获取当前线程对象,然后获取这个Thread对象的threadLocals,如果不为空,就根据当前ThreadLocal对象key获取值并返回,如果为空,那就设置并返回初始值。

ThreadLocal使用demo

ThreadLocal可以用来存储线程级上下文,一个demo如下:

import java.util.TimeZone;public class MyContext {private ThreadLocal<String> tenantSpaceId;private ThreadLocal<TimeZone> userTimeZone;private static MyContext instance = new MyContext();private MyContext() {tenantSpaceId = new ThreadLocal<>();userTimeZone = new ThreadLocal<>();}public static MyContext getInstance() {return instance;}public void setTenantSpaceId(String tsi) {tenantSpaceId.set(tsi);}public String getTenantSpaceId() {return tenantSpaceId.get();}public void setUserTimeZone(TimeZone tz) {userTimeZone.set(tz);}public TimeZone getUserTimeZone() {return userTimeZone.get();}public void clear() {tenantSpaceId.remove();userTimeZone.remove();}}

Java线程局部变量ThreadLocal相关推荐

  1. 线程局部变量 ThreadLocal

    文章目录 线程局部变量 ThreadLocal ThreadLocal 的作用和目的 ThreadLocal 的应用场景 ThreadLocal 的使用方式 (1) 在关联数据类中创建 private ...

  2. java线程间ThreadLocal的传递

    文章目录 1 场景 2 需确认问题 2.1 继承线程的ThreadLocal的含义 2.2 子线程内的ThreadLocal的值和父线程内的有什么关系? 2.3 父线程内的ThreadLocal清除后 ...

  3. Java并发之ThreadLocal

    作者:@adamhand zybuluo.com/adamhand/note/1370920 ThreadLocal是什么 首先说明,ThreadLocal与线程同步无关.ThreadLocal虽然提 ...

  4. JAVA线程本地变量ThreadLocal和私有变量的区别

    ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些. 所以,在Java中编写线程局部变量的代码相对来说要笨 ...

  5. java 线程变量put_Java线程(篇外篇):线程本地变量ThreadLocal

    首先说明ThreadLocal存放的值是线程内共享的,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递,这样处理后,能够优雅的解决一些实际问题,比如hibernate中的OpenSessi ...

  6. Java小白的入门面试笔记--线程局部变量之灵魂四问

    1.ThreadLocal 是什么? ThreadLocal俗名叫做线程局部变量,就是由ThreadLocal通过set方法填充的变量,它是只属于当前的线程,对于其他的线程来说是隔离的,是当前线程独有 ...

  7. 2017年50道Java线程面试题

    下面是Java线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编 ...

  8. java线程 同步与异步 线程池

    1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成的,有时为了解 决此问题,优先考虑 ...

  9. Java线程面试题 Top 50(转)

    不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎.大多数待遇丰厚的Java开发职位都要求开发者精通多线程 ...

最新文章

  1. 2022-2028年中国自动化设备市场研究及前瞻分析报告
  2. 万字解读:预训练模型最新综述!
  3. mySQL(关系型数据库管理系统)编辑
  4. 虚拟机登陆别的服务器吗,云服务器只能用虚拟机登录吗
  5. memset()函数的赋值问题
  6. nginx 1.14.0 配置部署 thinkphp 5.1
  7. 加权最小二乘法的原理讲解
  8. blob的真实地址怎么获得_使用Python抓取m3u8加密视频 续:获得index.m3u8 地址
  9. Animate.css介绍
  10. [WCF] - 使用 [DataMember] 标记的数据契约需要声明 Set 方法
  11. C++11新特性之左值右值及移动语句与完美转发
  12. Tortoiser三十集脱壳教程__ZC
  13. WPS文档批量转换成PDF
  14. ffmpeg笔记(一)音视频基础
  15. poj2391 Ombrophobic Bovines 拆点连边要注意
  16. 【我的Android进阶之旅】解决使用DiskLruCache报错: keys must match regex [a-z0-9_-]{1,64}
  17. 艾克---BBB时间设置
  18. 电动车治理再度升级,多地将有“新变化”
  19. day28 re(正则)模块
  20. R语言中的异常处理和eval函数

热门文章

  1. 马云现身敦煌种梭梭树:蚂蚁森林即将突破1亿棵树
  2. django中URL常用配置方法
  3. 晨哥真有料丨你喜欢人家啊,你追求人家。你到了什么地步就该放弃了?
  4. 摄像头图像分析目标物体大小位置_对智能驾驶系统三种环境传感器布局的冗余关系分析...
  5. 服务器报告它来自digest_2020年全球服务器市场规模及竞争格局分析
  6. Linux网络转发和端口映射的笔记
  7. Linux下挂载NTFS格式文件系统
  8. Chrome 无法抓取跳转请求的解决办法
  9. 在拦截器里放入参数 controller_干货|SpringMVC拦截器的使用详解
  10. javascript案例大全_JavaScript 中文资源大全,你值得拥有