ThreadLocal 变量和 与线程池配合使用时可能会出现的问题
ThreadLocal 变量和 与线程池配合使用时可能会出现的问题
ThreadLocal 的介绍和使用
先看下ThreadLocal变量的使用
public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);} //获取Thread类里面的 ThreadLocalMap 变量ThreadLocalMap getMap(Thread t) {return t.threadLocals;}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();}
可以看出来,ThreadLocal就是在每个线程 Thread 类里的变量 ThreadLocalMap。
而ThreadLocalMap 这个Map和HashMap类似。
从这可以看出来,ThreadLocal 中有一个在每个线程中不一样的Map(因为是Thread类的成员变量),所以实现了一个多个线程隔离的数据集。
线程池的回顾
线程池的实现中,启动的工作线程如果有工作会一直工作,直到workQueue中的数据没有,并且超过了pollingTime才会销毁这个工作线程。
两者结合的问题
所以在使用线程池的时候再使用 ThreadLocal 变量就会有一个,同一个工作线程执行不同的任务时,ThreadLocal变量就会有脏读的现象。来看一个例子:
public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(2);final ThreadLocal<String> threadLocal = new ThreadLocal<String>();Runnable runnable = new Runnable() {public void run() {System.out.println(threadLocal.get() == null);threadLocal.set(Thread.currentThread().getName()+": name");}};executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.shutdown();}
console中打印的数据:
true
true
false
false
false
false
结论
由上面的console中打印的数据可以看出来,在提交后面几个任务的时候 threadLocal都不是空值了。即说明
线程池中多个任务可能会使用同一个 ThreadLocal,原因是线程池可能会使用公用的线程来执行任务
ThreadLocal 变量和 与线程池配合使用时可能会出现的问题相关推荐
- c语言 线程a每隔10秒执行一次,线程b每隔100秒执行一次,线程池执行时多线程每隔100ms执行一次线程任务 求解答...
MobileData data = listData.get(i); //data.setI(i); //Thread.sleep(100);//多线程调用接口的时候每隔100ms调用一次 //多线程 ...
- 通过transmittable-thread-local源码理解线程池线程本地变量传递的原理
前提 最近一两个月花了很大的功夫做UCloud服务和中间件迁移到阿里云的工作,没什么空闲时间撸文.想起很早之前写过ThreadLocal的源码分析相关文章,里面提到了ThreadLocal存在一个不能 ...
- Java线程池ThreadPoolExecutor回收线程时执行资源回收操作
背景 一般来说,由于Java有垃圾回收机制存在,只需要确保不要写出内存泄露的代码,不需要手动回收资源.然而有时候Java程序会依赖一些外部的资源,如在线程池中调用浏览器爬取网页时,为了避免频繁打开浏览 ...
- 如何关闭线程池?会创建不会关闭?调用关闭方法时线程池里的线程如何反应?
前言 相信大家在面试的时候经常会遇到「线程池」相关的问题,比如: 什么是线程池?线程池的优点? 有哪几种创建线程池的方式? 四种创建线程池的使用场景? 线程池的底层原理? 线程池相关的参数,比如Cor ...
- Java 新建线程时使用线程池处理
说明: 线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险. Executors各个方法 ...
- Java多线程系列--【JUC线程池 02】- 线程池原理(一)
参考:http://www.cnblogs.com/skywang12345/p/java_threads_category.html 概要 在前面一章"Java多线程系列--"J ...
- 一篇搞定企业级C++跨平台线程池
线程池在平时工作开发中是用的比较多的,例如后端开发中和数据库的交互,单线程在很多场景下受限于数据库连接性能限制,速度不理想,此时采用线程池+连接池,就可以更高性能的和数据库进行交互. C++标准库轮子 ...
- 多线程与高并发 笔记,非面向初学者 二:java引用,高并发多线程容器,线程池
网页右边,向下滑有目录索引,可以根据标题跳转到你想看的内容 如果右边没有就找找左边 上一节:JUC锁,一些面试题和源码讲解 1.引用 java引用共4种,强软弱虚 强引用:我们普通的new一个对象,就 ...
- Java线程池详细介绍——原理及详细使用
原文链接:https://www.toutiao.com/i6846340200134607374/ 关于线程和线程池的学习,我们可以从以下几个方面入手: 第一,什么是线程,线程和进程的区别是什么 第 ...
最新文章
- 使用sbt编译打包,spark-submit命令提交的详细步骤
- amaze ui各个模块简单说明
- 【翻译】在Sencha应用程序中使用插件和混入
- OSError: mysql_config not found
- Head.First.Object-Oriented.Design.and.Analysis《深入浅出面向对象的分析与设计》读书笔记(七)...
- 本科、硕士、博士的区别
- 51单片机c语言秒表,51单片机秒表C程序
- 小刘同学的CMOS模拟集成电路学习小记(不停更新)
- 三星手机如何分屏_艺术大片如何拍?快拜三星Galaxy S20 5G系列为师|三星|摄像头|手机|远景...
- Java接口练习(组装电脑)
- Matlab入门基础 note1——赋值与小数
- 【CVPR20超分】Zooming Slow-Mo: Fast and Accurate One-Stage Space-Time Video Super-Resolution
- 一个队长应该干什么?
- stream銆俠oxed_电脑关机时显示OX100672ed指令引用的OX0000000C内存,该内存不能为written是什么意思...
- Java程序员从携程、美团、阿里面试回来,这些面经分享给大家
- 最新PHP开源采集器/蓝天采集器系统源码
- 什么是随机种子(random seed)?
- 高德地图引入Vue添加POI搜索功能、marker点标记、通过经纬度逆编码过程
- MySQL的优化,至尊奢华版
- Zabbix5.0编译升级至6.0操作手册
热门文章
- java 位运算符赋值_java-运算符(算术、赋值 =、关系、逻辑、三元、位运算符)...
- 【机器学习算法专题(蓄力计划)】十九、机器学习中SVM算法代码实操
- 四十八、微信小程序开发系统组件
- 二十、欢迎来到掘金量化
- CoSENT:比Sentence-BERT更有效的句向量方案
- 多篇顶会看个体因果推断(ITE)的前世今生
- 当深度学习遇上量化交易——因子挖掘篇
- 【天池赛事】零基础入门语义分割-地表建筑物识别
- php域名转发,php 域名转发程序
- 【Linux病毒】腾讯云 cron、sshd 进程CPU占用超95%(亡命徒 Outlaw 僵尸网络攻击)问题排查及处理步骤