ThreadLocal总结

ThreadLocal总结

  • ThreadLocal作用:为每一个线程开辟一个副本,意思是线程本地

1、代码证明ThreadLocal为每个线程创建线程

线程==>
public class ThreadDemo extends Thread {

    ThreadLocal<Long> threadLocal;

    public ThreadDemo(ThreadLocal<Long> threadLocal) {
        this.threadLocal = threadLocal;
    }

    @Override
    public void run() {
        Long result = threadLocal.get();
        if (result == null) {
            threadLocal.set(System.currentTimeMillis());
            System.out.println(Thread.currentThread().getName() + "===>" + threadLocal.get()+"===>"+threadLocal);
        }
    }
}


证明==>

public class ThreadLocalDemo {

    public static ThreadLocal<Long> threadLocal = new ThreadLocal();

    public static void main(String[] args) {
        ThreadDemo t1 = new ThreadDemo(threadLocal);
        ThreadDemo t2 = new ThreadDemo(threadLocal);
        t1.start();
        try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
        t2.start();

    }

}

2、为什么为线程创建副本:分析ThreadLocal的get/set方法

set=====>

public void set(T value) {
    //获取当前线程
    Thread t = Thread.currentThread();
    //获得当前线程的成员变量,类型为ThreadLocal.ThreadLocalMap
    ThreadLocalMap map = getMap(t);
    if (map != null)
        //key:this,就是当前线程;value:就是存入的泛型值
        map.set(this, value);
    else
        createMap(t, value);
}

get ====>

public T get() {
        //获取当前线程
        Thread t = Thread.currentThread();
        //获得当前线程的成员变量,类型为ThreadLocal.ThreadLocalMap
        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();
    }


3、实际解决了什么?

mybatis内部sqlsession其内部就是采用ThreadLocal

爬虫每个Request的代理利用ThreadLocal

4、产生了什么问题?

内存泄露;
比如线程池核心线程之外的线程执行完任务,但是ThreadLocal没有释放,就会导致内存泄露
解决:可以通过delete()删除

posted @ 2020-10-19 23:26  木叶小寒江  阅读(138)  评论(0编辑  收藏  举报