面试分析:你懂不懂threadlocal?

目录

ThreadLocal

应用场景

get与set方法

ThreadLocalMap

ThreadLocalMap.set

 ThreadLocalMap.get

 ThreadLocalMap.remove

线程隔离

内存泄漏


今天看一个面试题,threadlocal的原理

首先,要知道threadlocal是什么,如果都不知道这个是什么,那就也别看什么原理了.....

ThreadLocal

threadlocal 是线程的内部存储类,可以在指定线程内存储数据,且只有指定线程可以拿到数据

说白了,就是为了数据安全

不同的线程在使用 threadlocal 的时候,都会有自己的一个 threadlocalmap 对象,并且通过 threadlocal 进行管理

每个新线程都会被实例化一个 threadlocalmap,并且赋值给 threadLocals,如果已经存在了 threadLocals,那就直接复用

应用场景

那种作用域是线程,并且不同的线程还会有不同的副本的时候,就可以考虑用 threadlocal

当然,如果说业务处理逻辑强依赖与 副本变量,那可能就不大适合这玩意了

get与set方法

这一块我们可以直接看源码就行

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
    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();
    }

可以看到,无论是 get 还是 set,都是用的 ThreadLocalMap 的方法

ThreadLocalMap

ThreadLocalMap 为每个 thread 都维护了一个数组 table,threadllcal 确定了一个数组下标,而这个下标是value存储的对应位置

从之前的 set 源码,我们可以得到,ThreadLocalMap 是一个延迟创建的结构,也就是说,至少要放置一个内容时才会创建

而通过创建 ThreadLocalMap 的源码,我们可以得到,ThreadLocalMap 初始化时创建了默认长度是16的 Entry 数组。通过 hashCode 与 length 位运算确定索引值 i

ThreadLocalMap.set

我们来看看 threadLocalMap 的 set 方法

 ThreadLocalMap.get

get 方法没有什么可看的,就直接取就完事了

 ThreadLocalMap.remove

我们再看看 remove 方法

        private void remove(ThreadLocal<?> key) {
            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);
            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) {
                if (e.get() == key) {
                    e.clear();
                    expungeStaleEntry(i);
                    return;
                }
            }
        }

可以看到,也没什么东西

线程隔离

threadlocal 拥有线程隔离特性,只有线程内可以访问

类比 synchronized,它是通过线程等待来解决访问冲突问题

而 threadlocal 是通过空间存储来解决访问冲突问题

内存泄漏

注意,threadlocal 有一个地方需要注意,那就是内存泄漏的问题,使用完,一定要 remove,否则永远清除不掉,时间长了就会出问题了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值