这段时间在重构项目的代码,把项目主体的实现方式做了调整,ThreadLocal在其中扮演了非常重要的角色。

需求(使用场景):客户端有一个请求过来,Java程序根据请求报文的参数决定调用某个服务提供数据。相信大家都会有类似的需求,拿我们业务来说,请求报文如下:

{"appid": "88888888","userid": 80,"datatype": "***","data":"{\"dataids\":[146,147,148]}"
}

一个用户请求过来,需要根据datatype字段决定调不同的服务。

  网上真的很多乱七八糟文章,讲ThreadLocal中的ThreadLocalMap存放的key是线程对象,value是设置的线程局部变量,觉得挺有道理的,正好实现了线程数据隔离。但是仔细看源码。发现每个Thread对象都维护了一个私有的ThreadLocalMap对象,ThreadLocalMap对象key是ThreadLocal对象,value是设置的变量值。这就有点扯了,看下面的示例代码,反正这样设计我是看不出来有什么好处,因为每个线程中会放置N个变量,那我就new N个ThreadLocal对象,Thread中的ThreadLocalMap维护的map key存放ThreadLocal对象,value放置值。

public class ThreadLocal<T> {public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);  //拿到线程私有的ThreadLocalMapif (map != null)map.set(this, value);  //Thread对象中 map key是ThreadLocal对象 elsecreateMap(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) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);  }ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {table = new Entry[INITIAL_CAPACITY];int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); //hashcode & 运算去除高位table[i] = new Entry(firstKey, firstValue);size = 1;setThreshold(INITIAL_CAPACITY);}
}

所以看到源码之后,那些讲ThreadLocal销毁之后,Thread -> ThreadLoalMap -> Entry[ WeakRefrence, Object]  因为线程还在,线程维护的Map的Entry数组也还存在,那数组中Entry的key是ThreadLocal的弱引用,value是值。所以会有内容泄漏的风险,所以最好是在使用完之后手动调用remove()函数。

至于源码中那些涉及Map在数组位置的求值,rehash我觉得都差不多,因为16的初始大小我认为是够的,因为很少会使用创建16个ThreadLocal对象。

 public static void main(String[] args) {ThreadLocal<Person> threadLocal = new ThreadLocal<>(); //每个线程局部变量都需要创建一个ThreadLocal对象ThreadLocal<String> threadLocal2 = new ThreadLocal<>();AtomicInteger atomicInteger = new AtomicInteger(1000);ExecutorService executorService = Executors.newCachedThreadPool();     //for(int i 0->10)executorService.submit(() -> {Person person = new Person();person.setIdcard(atomicInteger.getAndIncrement());person.setName(Thread.currentThread().getName());threadLocal.set(person);threadLocal2.set("haha");System.out.println(threadLocal.get());System.out.println(threadLocal2.get());System.out.println();threadLocal.remove();});executorService.shutdown();}

转载于:https://www.cnblogs.com/zhengwangzw/p/9669194.html

ThreadLocal实践相关推荐

  1. 面试官系统精讲Java源码及大厂真题 - 44 场景实战:ThreadLocal 在上下文传值场景下的实践

    44 场景实战:ThreadLocal 在上下文传值场景下的实践 开篇语 我们在 <打动面试官:线程池流程编排中的运用实战>一文中将流程引擎简单地完善了一下,本文在其基础上继续进行改造,建 ...

  2. JUC第六讲:ThreadLocal/InheritableThreadLocal详解/TTL-MDC日志上下文实践

    本文是JUC第六讲:ThreadLocal/InheritableThreadLocal详解.ThreadLocal无论在项目开发还是面试中都会经常碰到,本文就 ThreadLocal 的使用.主要方 ...

  3. threadlocal的应用场合_Redis深度历险:核心原理和应用实践(阅读笔记)2

    应用 1 : 千帆竞发 -- 分布式锁 分布式锁 分布式锁本质上要实现的目标就是在 Redis 里面占一个"茅坑",当别的进程也要来占时,发现已经有人蹲在那里了,就只好放弃或者稍后 ...

  4. JDK8 ThreadLocal 源码解析与最佳实践

    文章目录 用法 Example1 Example2 Springboot @Transcation 注解的原理 Entry 的 Key 设置为弱引用有什么好处 内存泄漏问题 This class pr ...

  5. FastThreadLocal吞吐量居然是ThreadLocal的3倍

    目前关于FastThreadLocal的很多文章都有点老有点过时了(本文将澄清几个误区),很多文章关于FastThreadLocal介绍的也不全,希望本篇文章可以带你彻底理解FastThreadLoc ...

  6. Atitit.软件兼容性原理与实践 v3 q326.docx

    Atitit.软件兼容性原理与实践 v3 q326.docx 1. 架构兼容性1 2. Api兼容性1 2.1. 新api  vs  修改旧的api1 3. Web方面的兼容性(js,html)1 3 ...

  7. 吊打 ThreadLocal!

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:https://blog.csdn.net/mycs2012/article/details/90898128 FastThr ...

  8. 一个ThreadLocal和面试官大战30个回合

    点击关注公众号,Java干货及时送达 开场 杭州某商务楼里,正发生着一起求职者和面试官的battle. 面试官:你先自我介绍一下. 安琪拉:面试官你好,我是草丛三婊,最强中单(妲己不服),草地摩托车车 ...

  9. ZooKeeper 源码和实践揭秘

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:runnerzhang,腾讯 CSIG 后台开发工程 ...

最新文章

  1. iOS crash 崩溃问题的追踪方法
  2. 【转】推荐10本C#编程的最佳书籍
  3. 解决IE6下,给图片加上line-height属性不起作用的方法
  4. [集训队作业2018] 三角形(贪心,堆,线段树合并)
  5. oracle查询慢怎么优化,Oracle查询优化-怎样建立索引优化下面的查询语句啊
  6. Redis-集合(Set)基础
  7. 【Java数据结构与算法】第三章 双向链表和约瑟夫问题
  8. 0顶会入场大厂算法岗的正确姿势(干货总结)
  9. laravel本地项目上传服务器,laravel 上传本地文件到服务器
  10. 使用git软件上传文件到自己的github当中去
  11. 初识马尔科夫链,原来是这样的
  12. 使用tesseract-ocr进行文字识别
  13. 【MATLAB】创建网格图和曲面图
  14. python爬取行业数据_Python爬取拉钩招聘网,让你清楚了解Python行业
  15. Java开发买低压本还是标压本_别看游戏本不用低压CPU,其实低压CPU成本比标压CPU更高!...
  16. vue——实现组织架构图(vue-org-tree)——技能提升
  17. LaTex - PPT 模板-1 (亲测可用)
  18. 用vba创建图表分析上市公司财报
  19. 3.7. Miscellaneous
  20. 乐高 计算机泡泡龙教案,科学小实验----有趣的泡泡龙

热门文章

  1. yii 全选 php,yii2中gridview使用技巧小结(四)——全选等批量操作
  2. php查询跳转结果页面,登录判断跳转页面
  3. linux mysql 不稳定_Linux服务器mysql数据库自动停止的解决方法 | 很文博客
  4. php libmysqlclient,什么是php?以及mysqlnd与libmysqlclient
  5. python ssh登陆模块_Python sshh包_程序模块 - PyPI - Python中文网
  6. html配置ss,#WEB安全基础 : HTML/CSS | 0x8CSS进阶
  7. 【视频课】8大Pytorch CV实践案例,超30小时视频助你攻略CV三大基础任务(分类分割检测)
  8. 【赠书】pandas创始人手把手教你利用Python进行数据分析
  9. 【有三吐槽】程序员改BUG的六重境界,你,第几重了?
  10. 全球及中国无服务器应用程序行业应用调研与投资前景规划报告2022版