ThreadLocal简析

相信熟悉多线程的小伙伴,都熟悉这个对象的吧,今天咱们就来看一下他的内部构造以及和Thread的关系吧.
一切从set开始…

public void set(T value) {
        Thread t = Thread.currentThread();//获取当前线程的id
        ThreadLocalMap map = getMap(t);//从线程中获取当前的map
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

看一下getMap(t)操作:

ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;//着重说明一下,这个threadLocals对象放在Thread对象中的
    }

看一下这个threadLocals变量对应类型的数据结构:

/**
 * The table, resized as necessary.
  * table.length MUST always be a power of two.
  */
 private Entry[] table;//ThreadLocalMap基于一个数组实现的类似hashmap的实现

看一下Entry的结构:

static class Entry extends WeakReference<ThreadLocal<?>> {//继承了弱引用,在每次垃圾回收时,如果判定为弱可达,则进行垃圾回收
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);//着重点出,弱引用回收对象是ThreadLocal对象
                value = v;
            }
        }

再详细说明一下:

ThreadLocal tl = new ThreadLocal();
tl.set("测试值");

在当前Thread对象的ThreadLocalMap中是这么存储的key=tl,value=“测试值”,也就是tl = “测试值”

基本的结构说完了,再说一下ThreadLocal内存泄漏的问题:
一般来说内存泄漏时因为ThreadLocal对象包装成弱引用,在下一次gc时已经进行垃圾回收,那么value呢??还是一直存在的…这就造成了泄漏了.一般来说只要value不是很大,这点泄漏不会导致什么大的问题,并且当线程停止后,也会进行回收.

可是咱们很多时候使用ThreadLocal是这么用的

static ThreadLocal tl = newThreadLocal();

像这种情况,弱引用就失效了,静态关键字延长了tl的生命周期.如果是普通使用问题不会很大,如果是线程池配合该tl使用,会导致很多问题.
1.可能导致从tl中获取的结果不是想要的
2.如果tl对应的val是复杂类型,如map,当任务每次放入的key不同时,因为一直得不到释放,很容易造成不断累积,造成内存泄漏,这种情况比较严重;

建议:
在使用线程池技术时,如果确实用到了复杂类型,并且每次可能放入不容的key,那么尽量复写

protected void beforeExecute(Thread t, Runnable r) { }//或者
protected void afterExecute(Runnable r, Throwable t) { }

这两个方法中任意一个,在其中执行tl.remove()来清理任务本地存储.

如有不足,请留言指正.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值