ThreadLocal详解

ThreadLocal是用来存储每一个线程的数据的,使用set和get来读写数据。

ThreadLocal<Object> local = new ThreadLocal<>();
local.set(6);
System.out.println(local.get());

ThreadLocal是用来维护ThreadLocalMap的。set和get操作都是对ThreadLocalMap操作。


set方法

get方法

每一个Thread都有一个单独的ThreadLocalMap。



ThreadLocalMap定义是在Thread里面,使用是在threadlocal里面。
ThreadLocalMap其实是一个默认大小16的数组,一个线程的每一个ThreadLocal占用一个位置,这是通过ThreadLocalMap里面的threadLocalHashCode对数组长度取模实现的。


ThreadLocal内存溢出

存储数据的Entry的key的ThreadLocal采用的弱引用,能被清理掉,但是value是强引用,引用关系为:Thread -> ThreadLocalMap -> Entry -> Value,只要该线程不死,那么这个强引用就一直存在,不会被清理掉,导致内存溢出。


image.png

解决方法为:

虽然ThreadLocal的作者想到了这点,也做了些优化,例如在get的时候当发现key是null的时候,会遍历一次整个Entry数组,remove掉key为null的entry,把value指向null,消除这条强引用链。源码方法为expungeStaleEntry。
所以开发者要养成良好的习惯,记得用完ThreadLocal时,调一次ThreadLocal.remove()方法或者ThreadLocal.set(null)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 介绍 顾名思义这个类提供线程局部变量每个线程(通过其get或set方法)都有自己独立初始化的变量副本 Thread...
    Ray昱成阅读 263评论 0 0
  • ThreadLocal是一个关于创建线程局部变量的类。 通常情况下,我们创建的变量是可以被任何一个线程访问并修改的...
    icecrea阅读 753评论 0 2
  • 1 ThreadLocal简介 多线程访问同一个共享变量的时候容易出现并发问题,特别是多个线程对一个变量进行写入的...
    爱健身的兔子阅读 465评论 0 0
  • ThreadLocal是什么? ThreadLocal是一个关于创建线程局部变量的类。 通常情况下,我们创建的变量...
    chenjieping1995阅读 2,267评论 1 3
  • 引言 ThreadLocal的官方API解释为:“该类提供了线程局部 (thread-local) 变量。这些变量...
    小波同学阅读 397评论 0 3