zoukankan      html  css  js  c++  java
  • ThreadLocal

    1、Threadlocal 背景、原理

    背景:对于一个变量,如果多个线程需要操作该变量该怎么做,而且该变量在各个线程内还要代表不同的值(线程间不需要据此变量通信)

          对于上述问题,首先可以加锁解决,但是总感觉不够灵活,浪费资源;其实这就可以用 ThreadLocal

    原理:先写个例子再理解原理比较好(如下)

       这里就简单举例(每个线程在自己执行体内都调用 threadlocal设置了值或去获取值)

        public static void main(String[] args) throws InterruptedException {
    
            ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    
            //主线程设置下 最后取出
            threadLocal.set(100);
            Thread thead1 = new Thread(new Runnable() {
                @Override
                public void run() {
              //它会为null 因为你没在该执行体设置值 System.out.println(Thread.currentThread().getName()
    +"```:"+threadLocal.get());// null } }, "thead1"); thead1.start(); Thread thead2 = new Thread(new Runnable() { @Override public void run() { threadLocal.set(10) ; System.out.println(Thread.currentThread().getName()+"```:"+threadLocal.get());// null } }, "thead2"); thead2.start(); //这个只是为了等待线程1 2 执行完,让代码按顺序执行 thead1.join(); thead2.join(); //main线程 System.out.println(threadLocal.get());//100
    }

    原理:表面看上去是在 ThreadLocal 内存了值,其实并不是;threaLocal 只是一个key

               我们需要知道,每个线程都有自己的map (ThreadLocal.ThreadLocalMap threadLocals )

       这个 map 是以Entry为存储单元的数组,看源码很清晰的;

              所以,每个线程都会根据key计算想要存储的这个元素的位置(hash),确定之后,以 Entry 得形式存入,这个Entry也是key value;没错这个key就是threadLocal 和上述计算位置的key一样

              取得时候就根据线程自己的threadlocal去取即可,这就是原理

    另外ThreadLocal得另一个经典问题就是:内存泄漏;

    原因: 当一个生成生命周期很长得时候,加入你此时使用了threadLocal ,然后使用结束了,但是线程没结束,所以ThreadLocalMap依然存在,所以里面的key value 依然存在;这就造成了内存泄漏

    对策: Entry 里的key是一个虚引用,但它也仅仅是解决了key得回收问题,

        不过呢,value当然也可据此回收,判断key为null,那就对它进行回收,那不就妥了 哈哈

            所以,threadlocal 每次set get remove 都会去判断key对key进行回收,所以我们想避免那就记得不用了记得remove即可

    疑问:为啥不把value也置为虚引用?

     答:key 还没回收,value就没了,那你说咋办?

    疑问:key 为虚引用?能不能模拟一下咋就为虚引用了?

               你在线程内把threadlocal置为null,且其他地方别用;他就是虚引用了           

  • 相关阅读:
    Python 自动化测试实战训练营,由浅入深,从小白到测试高手!
    接口测试 Mock 实战(二) | 结合 jq 完成批量化的手工 Mock
    从文科生转行测试,再到大厂测试开发工程师,我是如何做到的?
    严正声明|严厉打击盗版侵权、非法销售「霍格沃兹测试学院」课程的违法行为
    「金羽毛」有奖征文 | 记录测试开发技术进阶之路的点滴
    测试工程师职业发展漫谈
    Workshop 深圳站|实战+源码架构剖析带你揭开Appium的神秘面纱
    那些难改的 Bug,最后都怎样了?
    BAT大厂都在用的Docker。学会这三招,面试、工作轻松hold住
    2021 开年学习送福利,助力测试进阶提升!
  • 原文地址:https://www.cnblogs.com/blog-tian/p/15545018.html
Copyright © 2011-2022 走看看