TreadLocal

80 阅读1分钟

ThreadLocal的使用

  1. ThreadLocal用来做什么

在不同线程内,通过TreadLocal对象的set()保存对象。通过ThreadLoacal对象的get()获取该线程对应保存的对象。

  1. 使用方法
public class Test {
    private static final ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    public void add() {
        threadLocal.set(1);
        doSamething();
        Integer integer = threadLocal.get();
    }
}

ThreadLoacl原理

每个线程维护一个ThreadLocalMap成员变量,有来存储要保存的数据。

TreadLocalMap是ThreadLocal的内部类。

在ThreadLocal的set()中,先获取到当前线程对象,通过线程对象获取线程维护的ThreadLocalMap对象。TreadLocalMap的set()传入的key是当前ThreadLocal对象,value是要存储的值。

public class ThreadLocal<T> {
     public T get() {
        //获取当前线程对象
        Thread t = Thread.currentThread();
        //通过Thread对象获取当前线程的成员变量ThreadLocalMap对象
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            //根据threadLocal对象从map中获取Entry对象
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                //获取保存的数据
                T result = (T)e.value;
                return result;
            }
        }
        //初始化数据
        return setInitialValue();
    }
    
    private T setInitialValue() {
        //获取要初始化的数据
        T value = initialValue();
        //获取当前线程
        Thread t = Thread.currentThread();
        //获取当前线程的成员变量ThreadLocalMap对象
        ThreadLocalMap map = getMap(t);
        //如果map不为空
        if (map != null)
            //将初始值设置到map中,key是this,即threadLocal对象,value是初始值
            map.set(this, value);
        else
           //如果map为空,则需要创建新的map对象
            createMap(t, value);
        return value;
    }
    
    public void set(T value) {
        //获取当前线程
        Thread t = Thread.currentThread();
        //获取当前线程的成员变量ThreadLocalMap对象
        ThreadLocalMap map = getMap(t);
        //如果map不为空
        if (map != null)
            //将值设置到map中,key是this,即threadLocal对象,value是传入的value值
            map.set(this, value);
        else
           //如果map为空,则需要创建新的map对象
            createMap(t, value);
    }
    
     static class ThreadLocalMap {
        ...
     }
}