这篇文章(看完了再看下面的)很好地解释了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. 同一台电脑同时使用gitHub和gitLab

    工作中我们有时可能会在同一台电脑上使用多个git账号,例如:公司的gitLab账号,个人的gitHub账号.怎样才能在使用gitlab与github时,切换成对应的账号,并且免密?这时我们需要使用ss ...

  2. MySQL - 常用三种数据库存储引擎

    数据库存储引擎:是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建.查询.更新和删除数据.不同的存储引擎提供不同的存储机制.索引技巧.锁定水平等功能,使用不同的存储引擎,还可以获得特 ...

  3. centos7安装kafka 转

    CentOS7安装和使用kafka         环境准备 安装kafka之前我们需要做一些环境的准备 1.centOS7系统环境 2.jdk环境 3.可用的zookeeper集群服务 安装jdk ...

  4. PHP 超级全局变量 $_GET

    https://www.php.cn/php/php-superglobals.html https://m.php.cn/code/11853.html

  5. IDEA 半天卡住buid(编译)不动

    [号外号外!] 最终解决办法并不复杂,关键在于"遇见问题,怎么样层层分析,多条路径试错,最终解决问题的思路或者能力"--资深码农的核心竞争力之一 背景 今天结束完最近2个月的一个项 ...

  6. Linux运维学习第六周记

    四月上夏渐热 善疗也须调摄 文殊眼裹抽筋 金刚脑后拔楔 网络的世界让人变得不那么真实! 第六周学记 用了一周的时间学习了计算机网络基础知识,说是基础,更应该说是必备的常识! 网络的协议和管理 TCP/ ...

  7. Linux 动态库加载

    动态库运行时搜索顺序 1.LD_PRELOAD LD_PRELOAD是一个环境变量,用于动态库加载,动态库加载的优先级最高: 2.-wl,-rpath 编译目标代码时指定的动态库搜索路径(指的是用-w ...

  8. 基于Python与命令行人脸识别项目(系列一)

    Face Recognition 人脸识别 摘要:本项目face_recognition是一个强大.简单.易上手的人脸识别开源项目,并且配备了完整的开发文档和应用案例,方便大家使用.对于本项目可以使用 ...

  9. APP后台架构开发实践笔记

    1 App后台入门 1.1 App后台的功能 (1)远程存储数据: (2)消息中转. 1.2 App后台架构 架构设计的流程 (1) 根据App的设计,梳理出App的业务流程: (2) 把每个业务流程 ...

  10. Apache POI 合并单元格--简单解释版带Demo

    合并单元格所使用的方法: sheet.addMergedRegion( CellRangeAddress  cellRangeAddress  );   CellRangeAddress  对象的构造 ...