ThreadLocal的方法

这篇博客探讨了ThreadLocal的几个关键方法,包括initialValue()、setInitialValue()、set()、get()和remove()。initialValue()允许自定义初始值,setInitialValue()和set()用于设置值,get()用于获取值,而remove()则用于移除键值对。在使用这些方法时,ThreadLocal会自动清理ThreadLocalMap中key为null的value。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ThreadLocal

当很多线程需要多次使用同一个对象,并且需要该对象具有相同初始化值的时候最适合使用ThreadLocal
	简单来说,就是操作线程中的ThreadLocalMap ,ThreadLocalMap 中包含了一个Entry数据用来存放多个(threadLoacl和value的键值对)

Thread 类中包含一个ThreadLocalMap类
ThreadLocal.ThreadLocalMap threadLocals = null;

ThreadLocal 中有一个initialValue() setInitialValue() set(T value)方法,get()方法和remove()方法

initialValue()就是返回初始值,可以重写来实现自己的初始值
setInitialValue() 是设置初始值并返回初始值
set(T value)方法 为当前线程的threadLocals中设置value值

 public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t); //return t.threadLocals;
        if (map != null)
            map.set(this, value); //为此此线程的ThreadLocalMap 中设置一个threadLoacl和value的键值对
        else
            createMap(t, value);
    }

get() 从当前线程的ThreadLocalMap 中的Entry数组中获取 此threadlocal的值

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();
    }

remove()
从当前线程的ThreadLocalMap 中的Entry数组中把这个threadlocal和value的键值对置为null

public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }
     
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;
                }
            }
        }
static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
ThreadLocalMap使用ThreadLocal的弱引用作为key,
如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,
这个ThreadLocal势必会被回收,这样一来,ThreadLocalMap中就会出现key为nullEntry,就没有办法访问这些key为nullEntry的value,如果当前线程再迟迟不结束的话(线程池重用线程),
这些key为nullEntry的value就会一直存在一条强引用链:
Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远无法回收,
造成内存泄漏。


ThreadLocal的措施
get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value
但无法保证

    static的ThreadLocal,延长了ThreadLocal的生命周期,可能导致的内存泄漏
    分配使用了ThreadLocal又不再调用get(),set(),remove()方法,那么就会导致内存泄漏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值