这篇文章(看完了再看下面的)很好地解释了ThreadLocal是什么,怎么用,是否能解决线程安全问题,非常nice。但个人认为讲解存在遗漏,进行如下示例补充:

  • InheritableThreadLocal
public class ThreadIdService {
private static ThreadLocal<User> localUser=new InheritableThreadLocal<>();
public static void main(String[] args) {
User user = new User();
user.setName("main");
localUser.set(user);
System.out.println("main threadUser:"+localUser.get());
Thread t1 = new Thread() {
@Override
public void run() {
System.out.println("t1User:"+localUser.get());
localUser.get().setName("1");
System.out.println("t1User:"+localUser.get());
}
};
Thread t2 = new Thread() {
@Override
public void run() {
User user2 = new User();
user2.setName("2");
localUser.set(user2);
System.out.println("t2User:"+localUser.get());
}
};
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main threadUser:" + localUser.get());
user.setName("main2");
}
}

  • ThreadLocal
public class ThreadIdService {
private static ThreadLocal<User> localUser=new ThreadLocal<>();
public static void main(String[] args) {
User user = new User();
user.setName("main");
localUser.set(user);
System.out.println("main threadUser:"+localUser.get());
Thread t1 = new Thread() {
@Override
public void run() {
System.out.println("t1User:"+localUser.get());
/*localUser.get().setName("1");
System.out.println("t1User:"+localUser.get());*/
}
};
Thread t2 = new Thread() {
@Override
public void run() {
User user2 = new User();
user2.setName("2");
localUser.set(user2);
System.out.println("t2User:"+localUser.get());
}
};
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main threadUser:" + localUser.get());
user.setName("main2");
}
}

  • 总结:
  1. ThreadLocal能起到线程件变量隔离的作用。
  2. InheritableThreadLocal则未必,若每个线程存放在InheritableThreadLocal的变量都采用new Object()的方式,则各线程间互不影响,否则传递的是引用,牵一发而动全身!!!
  3. InheritableThreadLocal之所以能够完成线程间变量的传递,是在new Thread()的时候对inheritableThreadLocals对像里的值进行了复制。
  4. 子线程通过继承得到的InheritableThreadLocal里的值与父线程里的InheritableThreadLocal的值具有相同的引用,如果父子线程想实现不影响各自的对象,可以重写InheritableThreadLocal的childValue方法。

关于ThreadLocal的那些事的更多相关文章

  1. 谈谈Java引用和Threadlocal的那些事

    1 背景 某一天在某一个群里面的某个群友突然提出了一个问题:"threadlocal的key是虚引用,那么在threadlocal.get()的时候,发生GC之后,key是否是null?&q ...

  2. 浅谈Java引用和Threadlocal的那些事

      这篇文章主要介绍了Java引用和Threadlocal的那些事,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 1 背景 某一天在某一个群里面的某个群友突然提出了一个问 ...

  3. 架构探险笔记6-ThreadLocal简介

    什么是ThreadLocal? ThreadLocal直译为“线程本地”或“本地线程”,如果真的这么认为,那就错了!其实它就是一个容器,用于存放线程的局部变量,应该叫ThreadLocalVariab ...

  4. java jdbc深入理解(connection与threadlocal与数据库连接池和事务实)

    1.jdbc连接数据库,就这样子 Class.forName("com.mysql.jdbc.Driver");java.sql.Connection conn = DriverM ...

  5. 切换数据库+ThreadLocal+AbstractRoutingDataSource 一

    最近项目用的数据库要整合成一个,所以把多源数据库切换的写法要清除掉.所以以下记载了多远数据库切换的用法及个人对源码的理解. 框架:Spring+mybatis+vertx,(多源数据库切换的用法不涉及 ...

  6. paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)

    paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象) 1     锁的缺点 2     CAS(Compare ...

  7. 理解ThreadLocal背后的概念

    介绍 我之前在任何场合都没有使用过thread local,因此没有注意到它,直到最近用到它的时候. 前提信息 线程可以理解为一个单独的进程,它有自己的调用栈.在java中每一个线程都有一个调用栈或者 ...

  8. java concurrency: ThreadLocal及其实现机制

    转载:http://shmilyaw-hotmail-com.iteye.com/blog/1703382 ThreadLocal概念 从字面上来理解ThreadLocal,感觉就是相当于线程本地的. ...

  9. 详细领悟ThreadLocal变量

    关于对ThreadLocal变量的理解,我今天查看一下午的博客,自己也写了demo来测试来看自己的理解到底是不是那么回事.从看到博客引出不解,到仔细查看ThreadLocal源码(JDK1.8),我觉 ...

随机推荐

  1. 使用Python对植物大战僵尸学习研究

    根据上一篇 使用Python读写游戏1 中,使用Python win32库,对一款游戏进行了读内存 操作. 今天来写一下对内存进行写的操作 正文 要进行32位的读写,首先了解一下要用到的几个函数,通过 ...

  2. 【C语言C++编程学习笔记】基础语法,第一个简单的实例编程入门教程!

    C语言/C++编程学习:一个简单的实例 让我们来看一个简单的C语言程序.从下面的程序可以看出编写C语言程序的一些基本特征.   如果你能知道该程序将会在显示器上显示一些内容,那说明你还是知道一些的! ...

  3. [Leetcode题解]2. 两数相加-链表遍历和重构

    1. 审题leetcode 02 add-two-numbers​ 我们先看一下题目,如下  : 链表的从前往后为数字的低位到高位,模拟加法手算过程,从前往后遍历即可, 注意每个数字0-9,进位要处理 ...

  4. 转 RabbitMQ 入门教程(PHP版) 使用rabbitmq-delayed-message-exchange插件实现延迟功能

    延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...

  5. php生成器 yield 转

    一.yield介绍  文档介绍说道:生成器函数的核心是yield关键字.它最简单的调用形式看起来像一个return申明,不同之处在于普通return会返回值并终止函数的执行,而yield会返回一个值给 ...

  6. 第二十四章 IPtables防火墙

    一.iptables防火墙基本概述 1.应用场景 1.主机安全2.端口转发/ip转发3.内部共享上网 2.iptables工作流程 1.配置防火墙规则可以添加在下面,也可以添加在前面,是有顺序的2.匹 ...

  7. leaflet平台添加天地图方法

    leaflet平台添加天地图得方法具体如下操作 var map = L.map('map',  {   crs: L.CRS.EPSG4326,   zoomControl: true,   edit ...

  8. 《3D打印与工业制造》个人总结 —— 周吉瑞

    <3D打印与工业制造>个人总结 ---- 周吉瑞 JERRY_Z. ~ 2020 / 10 / 24 转载请注明出处!️ 目录 <3D打印与工业制造>个人总结 ---- 周吉瑞 ...

  9. CTF相关

    https://blog.csdn.net/zxl2016/article/details/96482763

  10. 一篇文章搞定Git——Git代码管理及使用规范

    一篇文章搞定Git--Git代码管理及使用规范   https://blog.csdn.net/weixin_42092278/article/details/90448721