ThreadLocal一个线程只能存放一个变量吗?想存多个怎么搞? - 知乎

你去看一下源码就明白了。答案:完全可以创建多个ThreadLocal对象。

每个Thread对象(对应每个线程),保存有一个threadLocals的ThreadLocalMap对象(一个map)。

// Thread.java
ThreadLocal.ThreadLocalMap threadLocals = null;

这个map就是用来存放你的ThreadLocal对象的,你创建一个,它就在那个线程的map上放一个元素,key为对应的ThreadLocal对象,value为ThreadLocal对象绑定的东西。

比如下面这个代码

String localVar = "123";
ThreadLocal<String> threadLocalObject = new ThreadLocal<String>();
threadLocalObject .set(localVar);

String str = threadLocalObject .get();

创建了一个ThreadLocal对象threadLocalObject ,并调用set方法绑定String对象localVar 。这一步做了什么可以看下面这张图

这个threadLocalObject会在currentThread(当前线程)对应的这个map上放一个Entry,key就是threadLocalObject,值为set的那个值。

当调用get时,threadLocalObject会取得当前线程的threadLocalMap然后以自身为key进行查找。

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

所以,你完全可以创建多个ThreadLocal对象,它实际上放在一个map上,不用你担心。

比如这样

String localVar1 = "123";
String localVar2 = "local";
Integer localVar3 = 1;

ThreadLocal<String> threadLocalObject1 = new ThreadLocal<String>();
ThreadLocal<Object> threadLocalObject2 = new ThreadLocal<Object>();
ThreadLocal<Integer> threadLocalObject3 = new ThreadLocal<Integer>();
threadLocalObject1 .set(localVar1);
threadLocalObject2 .set(localVar2);
threadLocalObject3 .set(localVar3);

而且,它这个Entry的Key,还是弱引用的,内存回收的问题,也不用你担心。

static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }

原网址: 访问
创建于: 2023-02-09 14:15:13
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论