java多线程

Java 多线程(四):ThreadLocal 详解

2018-03-12  本文已影响47人  聪明的奇瑞

ThreadLocal

ThreaLocal 接口方法

ThreadLocal 用法

public class TreadLocalTest {

    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();

    public static void main(String[] args) {
        for (int i = 0; i < 2; i++) {
            new Thread(new Runnable() {
                public void run() {
                    int data = new Random().nextInt();
                    System.out.println(Thread.currentThread().getName() + " put data :" + data);
                    threadLocal.set(data);

                    new A().get();
                }
            }).start();
        }
    }

    static class A {
        public void get() {
            int data = threadLocal.get();
            System.out.println(Thread.currentThread().getName() + " get data :" + data);
        }
    }
}
Thread-0 put data :-405727869
Thread-1 put data :-2129414360
Thread-0 get data :-405727869
Thread-1 get data :-2129414360

ThreadLocal 解决的问题

Spring 与 ThreadLocal 解决线程安全问题

ThreadLocal 内存泄露问题

static class Entry extends WeakReference<ThreadLocal<?>> {
    Object value;

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

ThreadLocal 源码分析

get 方法

    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            // 以当前的ThreadLocal 为 key,调用getEntry获取对应的存储实体e
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
    
    ThreadLocalMap getMap(Thread t) {
        // 获取当前线程Thread对应维护的ThreadLocalMap 
        return t.threadLocals;
    }

setInitialValue 方法

    // 返回该线程局部变量的初始值,该方法是一个 protected 的方法,目的是为了让子类重写而设计的
    protected T initialValue() {
        return null;
    }
    
    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;
    }

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

    // 为当前线程 Thread 创建对应维护的 ThreadLocalMap
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

remove 方法

    public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }
上一篇 下一篇

猜你喜欢

热点阅读