ThreadLocal是线程本地变量,每个线程中都存在副本。

实现原理:

每个线程中都有一个ThreadLocalMap,而ThreadLocalMap中的key即是ThreadLocal。

 内存泄漏:

ThreadLocal变量存储在栈内存中,对应对象存储在堆内存中,这个指向是强引用关系。

同样,ThreadLocalMap变量存储在栈内存中,对应对象key-value存储在堆内存中,也是强引用关系。同时map中的key也指向了threadlocal。

如果ThreadLocal变量被置为空,但是map仍存在引用,会导致堆中的对象无法释放,java已将map中的key优化为弱引用(WeakReference)。

但是value本身也存在强引用的关系,value并不会被释放,所以依然存在内存泄漏问题。

解决方法是,手动调用threadlocal的remove方法。

使用:

 1 public class Main {
2 private static ThreadLocal<Integer> tl = new ThreadLocal<>();
3 public static void main(String[] args) throws InterruptedException{
4 CountDownLatch c = new CountDownLatch(1);
5 ThreadPoolExecutor tpe = new ThreadPoolExecutor(10, 20, 60L, TimeUnit.SECONDS,
6 new ArrayBlockingQueue<>(3));
7 tpe.execute(new Runnable() {
8 @Override
9 public void run() {
10 System.out.println(Thread.currentThread().getName());
11 System.out.println(tl.get());
12 tl.set(1);
13 System.out.println(tl.get());
14 tl.remove();
15 c.countDown();
16 }
17 });
18 tpe.execute(new Runnable() {//模拟
19 @Override
20 public void run() {
21 try{c.await();}catch (InterruptedException e){};//让第一个线程先执行
22 System.out.println(Thread.currentThread().getName());
23 System.out.println(tl.get());
24 tl.set(2);
25 System.out.println(tl.get());
26 tl.remove();
27 }
28 });
29 tpe.shutdown();
30 }
31 }

应用场景:

1,Spring多数据源配置的切换;

2,Spring事务注解的实现;

3,日志框架slf4j中的MDC类的实现

待更多补充。

ThreadLocal实现原理和使用场景的更多相关文章

  1. ThreadLocal 原理和使用场景分析

    ThreadLocal 不知道大家有没有用过,但至少听说过,今天主要记录一下 ThreadLocal 的原理和使用场景. 使用场景 直接定位到 ThreadLocal 的源码,可以看到源码注释中有很清 ...

  2. 深入解析ThreadLocal 详解、实现原理、使用场景方法以及内存泄漏防范 多线程中篇(十七)

    简介 从名称看,ThreadLocal 也就是thread和local的组合,也就是一个thread有一个local的变量副本 ThreadLocal提供了线程的本地副本,也就是说每个线程将会拥有一个 ...

  3. 面试中的 ThreadLocal 原理和使用场景

    相信大家不管是在网上做题还是在面试中都经常被问过 ThreadLocal 的原理和用法,虽然一直知道这个东西的存在但是一直没有好好的研究一下原理,没有自己的知识体系.今天花点时间好好学习了一下,分享给 ...

  4. 线程局部变量ThreadLocal的原理及使用范围_1

    线程局部变量ThreadLocal的原理及使用范围 使用原理 每个Thread中都有一个ThreadLocalMap成员, 该成员是ThreadLocal的内部类ThreadLocalMap类型.每使 ...

  5. ThreadLocal的理解与应用场景分析

    对于Java ThreadLocal的理解与应用场景分析 一.对ThreadLocal理解 ThreadLocal提供一个方便的方式,可以根据不同的线程存放一些不同的特征属性,可以方便的在线程中进行存 ...

  6. Java进阶(七)正确理解Thread Local的原理与适用场景

    原创文章,始自发作者个人博客,转载请务必将下面这段话置于文章开头处(保留超链接). 本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ Th ...

  7. ThreadLocal的原理,源码深度分析及使用

    文章简介 ThreadLocal应该都比较熟悉,这篇文章会基于ThreadLocal的应用以及实现原理做一个全面的分析 内容导航 什么是ThreadLocal ThreadLocal的使用 分析Thr ...

  8. 【转】Thread Local的正确原理与适用场景

    本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ ThreadLocal解决什么问题 由于 ThreadLocal 支持范型,如 Thre ...

  9. ThreadLocal的实现和使用场景

    ThreadLocal 内部实现.应用场景和内存泄漏 深入理解线程局部变量:ThreadLocal <Java源码分析>:ThreadLocal /ThreadLocalMap Threa ...

  10. ThreadLocal的原理及产生的问题

    点赞再看,养成习惯,微信搜索「小大白日志」关注这个搬砖人. 文章不定期同步公众号,还有各种一线大厂面试原题.我的学习系列笔记. ThreadLocal的原理 特点 ThreadLocal和Sychro ...

随机推荐

  1. 关于TIdTCPClient的几种方法

    关于TIdTCPClient的几种方法 收藏  其实Indy比较简单,但是可以提供的方法太多了.我找了很久,才搞明白. 比方说这个读取缓冲区的数据,就有很多种方法.相对于TTcpClient的几种方法 ...

  2. 解决和根源:Unsolicited response received on idle HTTP channel starting with xxx

    环境:golang,使用http client,服务器:iis +aspx.net动作:head请求或其他此问题见于各种请求情况.核心是,http在活动期间收到了非预期的信息.一开始我也很纳-闷,因为 ...

  3. Step by Step: Connecting to Dynamics 365 using a C# Console App

    Step by Step: Connecting to Dynamics 365 using a C# Console App     If you're new to Microsoft Dynam ...

  4. R grep

    SAIN<-FAIN[grepl("HE-H$",FAIN$rDD),,drop=TRUE]

  5. 什么是js柯里化(curry)?

    在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术. 举例来说,一个接收3个参数的普通函数,在进行柯里化后,柯里化版本的函数接收一个参数并返回接收下一个参数 ...

  6. Linux 复制时排除某文件/目录

    如果要排除/home/data目录下面的a.b.c.三个目录,同时拷贝其它所有目录,执行rsync命令yum install rsync -y #安装rsync 排除单个文件/目录rsync -avP ...

  7. .bat 脚本替换文件内容

    rem 定义变量延迟环境,关闭回显 @echo off&setlocal enabledelayedexpansion rem 读取a.txt所有内容 for /f "eol=* t ...

  8. GameObject.Find()、Transform.Find()查找游戏对象

    GameObject.Find 按广度进行查找 GameObject.Find("GameObject"); GameObject.Find("GameObject/Ch ...

  9. mxnet的broadcast_power() 注释错误

    用relationnet时,发现broadcast_power()的源码中的注释如下: 官方文档中的注释如下: 怎么算都算不出它这个结果... 自己用mxnet实验了一把,发现是注释错了,代码如下:

  10. 解决docker容器不足问题

    df -h查看容量,看看那个被占满了,之前我这里是100% 用了一下docker system prune,发现没啥用,又加了-a:docker system prune -a,就又空间了. 之后再进 ...