ThreadLocal用法分析

1.ThreadLocal 简介

ThreadLocal为 多线程同步机制的 提供了解决思路,每个线程都可以去改变自己的变量副本,他们之间相互隔离,互不影响

2.ThreadLocal 的作用

让线程保存一份自己的变量副本,每个线程都独立使用自己的变量副本,这样就不会影响其他的线程

3.ThreadLocal 的内部机制 内部数据结构

维护了一个 ThreadLocalMap

由key-value 组成的entry 数组
key 是threadlocal 的 弱引用
value 对象线程变量的副本
在这里插入图片描述

4.ThreadLocal 的相关源码分析

4.1 删除方法
public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
 }
4.2 获取方法
public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
4.3 创建方法
private T setInitialValue() {
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }

5.ThreadLocal 在项目中的应用

5.1.session 是线程不安全的,因此在多线程环境下,session 不能为共享对象
5.2 每次运行都要打开以及关闭session 对象 导致性能受影响
综合以上以上因素,使用了ThreadLocal
private static final ThreadLocal<Map<String, Object>> SESSION_LOCAL = new ThreadLocal<>();
 /**
     * makeThreadValue
     *
     * @param key
     * @param value
     */
    public static <T> void makeThreadValue(String key, T value) {
        Map<String, Object> context = SESSION_LOCAL.get();

        if (context == null) {
            context = new ConcurrentHashMap<>();
            SESSION_LOCAL.set(context);
        }

        if (key != null && value != null) {
            context.put(key, value);
        }
    }

6.内存泄露问题

在这里插入图片描述
上图中,实线代表强引用,虚线代表的是弱引用,如果threadLocal外部强引用被置为null(threadLocalInstance=null)的话,threadLocal实例就没有一条引用链路可达,很显然在gc(垃圾回收)的时候势必会被回收,因此entry就存在key为null的情况,无法通过一个Key为null去访问到该entry的value。同时,就存在了这样一条引用链:threadRef->currentThread->threadLocalMap->entry->valueRef->valueMemory,导致在垃圾回收的时候进行可达性分析的时候,value可达从而不会被回收掉,但是该value永远不能被访问到,这样就存在了内存泄漏。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值