zoukankan      html  css  js  c++  java
  • 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()删除
    
    
  • 相关阅读:
    方法
    Go中的OOP
    GO 结构体
    指针
    闭包
    回调函数
    匿名函数
    函数的数据类型及本质
    defer语句
    递归函数
  • 原文地址:https://www.cnblogs.com/yejiang/p/13843946.html
Copyright © 2011-2022 走看看