• 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,且其他地方别用;他就是虚引用了           

  • 相关阅读:
    .net core api服务端跨域配置
    在.net core web 项目中使用Nlog记录日志
    在windows7系统下如何查看及升级powershell到3.0版本
    Prism框架中的事件聚合器EventAggregator(上)
    前端生成 guid 的方法
    冒泡排序的过程以及讲解
    关于isNaN() 判断是否是非数字
    BFC问题
    标准盒模型和怪异盒模型宽高计算!
    Python网络编程篇
  • 原文地址:https://www.cnblogs.com/blog-tian/p/15545018.html
Copyright © 2020-2023  润新知