前言:在一次面试过程中被问到ThreadLocal,大家都知道ThreadLocal可以为每个线程单独提供一个副本,从而实现变量间的隔离。在ThreadLocal中set和get操作的key是什么,ThreadLocal又是怎样实现各线程间互不干扰的,本文通过调试ThreadLocal的源码来阐述这些问题。

注:jdk版本:jdk1.7.0_51


1.set与get源码

   public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
  public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}

下面通过对源码的调试说明具体流程。

2.具体调试过程

 public class CodeTest02
{
public static void main(String[] args) throws InterruptedException
{
final ThreadLocal<Integer> threadLocal = new ThreadLocal<>(); Thread t1 = new Thread(new Runnable()
{
@Override
public void run()
{
threadLocal.set(1); System.out.println(threadLocal.get());
}
},"t1");
t1.start(); t1.join();
threadLocal.set(2); System.out.println(threadLocal.get()); } }

说明:在主线程和t1线程中进行set操作,最后输出如下:

从输出结果可以看出两个线程间的值互不影响。

具体调试过程:

注意:当前threadLocal的地址值为ThreadLocal@430。进入断点,如下图所示。

注意:

1)this的值为当前ThreadLocal对象的值(ThreadLocal@430)。

2)t表示当前线程t1。

3)map为空,注意这里的map为ThreadLocalMap。

转入createMap函数,传入的值为当前线程t1和value(value=1)。

说明:

1)createMap函数会为t1线程创建一个ThreadLocalMap。

从注释中可以看出,ThreadLocal为线程的附属值,所以ThreadLocalMap也为线程的一个附属属性,它被ThreadLocal维护。

2)该ThreadLocalMap的键为this,从调试信息中可以看出this的值为ThreadLocal@430。

接下来看get函数:

说明:

1)通过t1线程,取出ThreadLocalMap,这里获取set中根据t1创建的threadLocals对象。

  ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}

2)在ThreadLocalMap中根据this,也就是当前ThreadLocal@430,取得设置的值。

总结:

1)ThreadLocal中在set操作时,key为当前ThreadLocal对象

2)ThreadLocal会为每个线程都创建一个ThreadLocalMap,对应程序中的t.threadLocals = new ThreadLocalMap(this, firstValue),ThreadLocalMap为当前线程的属性。

3)通过对每个线程创建一个ThreadLocalMap实现本地副本。当取值时,实际上就是通过key在map中取值,当然此时的key为ThreadLocal对象,而map为每个线程独有的map,从而实现变量的互不干扰。


by Shawn Chen,2018.6.2日,下午。

ThreadLocal源码调试——“this”作为key的更多相关文章

  1. Java多线程9:ThreadLocal源码剖析

    ThreadLocal源码剖析 ThreadLocal其实比较简单,因为类里就三个public方法:set(T value).get().remove().先剖析源码清楚地知道ThreadLocal是 ...

  2. Java多线程学习之ThreadLocal源码分析

    0.概述 ThreadLocal,即线程本地变量,是一个以ThreadLocal对象为键.任意对象为值的存储结构.它可以将变量绑定到特定的线程上,使每个线程都拥有改变量的一个拷贝,各线程相同变量间互不 ...

  3. Java并发编程之ThreadLocal源码分析

    ## 1 一句话概括ThreadLocal<font face="微软雅黑" size=4>  什么是ThreadLocal?顾名思义:线程本地变量,它为每个使用该对象 ...

  4. ThreadLocal源码解读

    1. 背景 ThreadLocal源码解读,网上面早已经泛滥了,大多比较浅,甚至有的连基本原理都说的很有问题,包括百度搜索出来的第一篇高访问量博文,说ThreadLocal内部有个map,键为线程对象 ...

  5. 并发编程(四)—— ThreadLocal源码分析及内存泄露预防

    今天我们一起探讨下ThreadLocal的实现原理和源码分析.首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码分析了其实现原理和使用需要注意的地方,最后给出了两 ...

  6. SpringBoot自动配置源码调试

    之前对SpringBoot的自动配置原理进行了较为详细的介绍(https://www.cnblogs.com/stm32stm32/p/10560933.html),接下来就对自动配置进行源码调试,探 ...

  7. HashMap源码调试——认识"put"操作

    前言:通常大家都知道HashMap的底层数据结构为数组加链表的形式,但其put操作具体是怎样执行的呢,本文通过调试HashMap的源码来阐述这一问题. 注:jdk版本:jdk1.7.0_51 1.pu ...

  8. ThreadLocal详解,ThreadLocal源码分析,ThreadLocal图解

    本文脉路: 概念阐释 ---->  原理图解  ------> 源码分析 ------>  思路整理  ----> 其他补充. 一.概念阐述. ThreadLocal 是一个为 ...

  9. 【JAVA】ThreadLocal源码分析

    ThreadLocal内部是用一张哈希表来存储: static class ThreadLocalMap { static class Entry extends WeakReference<T ...

随机推荐

  1. .NET Core 实践二:事件通知和异步处理

    首先让我们来先看一个例子: 这是一个简单的用户下单购买商品的业务模型,输入端是用户,相关物料有订单和货物,相关的内部服务有业务(订单).财务(支付).仓储(备货)和物流(运输). 从图中我们可以看到, ...

  2. [nodejs] nodejs开发个人博客(四)数据模型

    数据库模型 /model/db.js 数据库操作类,完成链接数据库和数据库的增删查改 查询表 /*查询*/ select:function(tableName,callback,where,field ...

  3. 回客科技 面试的 实现ioc 容器用到的技术,简述BeanFactory的实现原理,大搜车面试的 spring 怎么实现的依赖注入(DI)

    前言:这几天的面试,感觉自己对spring 的整个掌握还是很薄弱.所以需要继续加强. 这里说明一下spring的这几个面试题,但是实际的感觉还是不对的,这种问题我认为需要真正读了spring的源码后说 ...

  4. js动画 Css提供的运动 js提供的运动

    1.     动画 (1)      Css样式提供了运动 过渡的属性transition  从一种情况到另一种情况叫过渡 Transition:attr  time  linear  delay: ...

  5. 价值1.35亿美元的BUG

    价值1.35亿美元的BUG 译者按: 一横值千金啊! 原文: Mariner 1’s $135 million software bug 译者: Fundebug 为了保证可读性,本文采用意译而非直译 ...

  6. 【软工神话】第五篇(Beta收官)

    前言:这应该是最后一章了,故事虽然到这就结束了,但现实里还要继续下去,希望在很久的以后来回顾时,能因自己学生时代有这样的经历而欣慰. 说明:故事中的人物均是化名,故事情节经过些许加工,故事情节并没有针 ...

  7. 【代码笔记】Web-Javascript-javascript break和continue语句

    一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  8. Dynamics 365 Online-Virtual Entities

    转载来源https://blogs.technet.microsoft.com/lystavlen/2017/09/08/virtual-entities/,使用当前Dynamics 365环境,亲测 ...

  9. mybatis 通过实体类进行查询

    如果使用实体类进行查询, 不管会不会使用到 主键, 都必须设置主键, 才能查询 <select id="selectByAppidAndServerCode" resultM ...

  10. Python 标准类库-日期类型之datetime模块

    标准类库-日期类型之datetime模块    by:授客 QQ:1033553122 可用类型 3 实践出真知 4 timedelta对象 4 class datetime.timedelta(da ...