线程数据共享必学的3个工具类: ThreadLocal InheritableThreadLocal TransmittableThreadLocal

线程数据共享必学的3个工具类:
ThreadLocal
InheritableThreadLocal
TransmittableThreadLocal

1.ThreadLocal:在当前线程中共享数据的,JUC 中提供的
2.InheritableThreadLocal:也是JUC中的一个工具类,解决 ThreadLocal 难以解决的问题
3.TransmittableThreadLocal:阿里开源的一个工具类,解决上面2个ThreadLocal 难以搞定的问题
也就是一个比一个强,也不能这么说,而是各有各的使用场景,

    private ThreadLocal<String> userNameItl = new ThreadLocal<>();
    // private InheritableThreadLocal<String> userNameItl = new InheritableThreadLocal<>();

    public void inheritableThreadLocal1() throws InterruptedException {
        userNameItl.set("张三");
        log.info("userName:{}", userNameItl.get());

        // 创建了一个子线程thread1,在子线程中区获取值
        new Thread(() -> {
            // ThreadLocal 时 userName:null

            /**
             * InheritableThreadLocal 时 userName:张三
             *
             * 存在的问题(子线程复制一次父线程之后,父子线程中的InheritableThreadLocal就没有关系了,父线程中|nheritableThreadLoca!的值再修改,也不会影响子线程中的值了)
             * 见:https://www.bilibili.com/video/BV1Pz421S7Wx/?spm_id_from=pageDriver&vd_source=deac72a1d60ac5149e7eb3f9a4998402
             * InheritableThreadLocal 如果用在线程池上,会有问题,可能导致严重的事故,这个一定要知道。
             *
             * 导致的原因:
             * 分析下结果
             * 从结果中看,线程池执行了2次任务,2次拿到的都是张三,和主线程第一次放入的值是一样的,而第二次主线程中放入的是李四啊,但是第二次线程池中拿到的却
             * 是张三,这是什么原因?
             * 上面线程池的大小是1,也就是说这个线程池中只有一个线程,所以让线程池执行的2次任务用到的都是一个线程,从上面的日志中可以看到线程名称都是 p001-1-
             * thread-1,说明这两次任务,都是线程池中同一个线程执行的。
             * 线程池中的线程是重复利用的,线程池中的po01-1-thread-1这个线程是什么时候创建的呢?谁创建的?他的父线程是谁?
             * 1.是主线程中第一次调用executorSerice.execute让线程池执行任务的时候,线程池发现当前线程数小于核心线程数,所以会创建一个线程
             * 2.他的父线程是谁?是创建他的线程,也就是执行第一次执行executorService.execute的线程,即主线程
             * 子线程创建的时候,子线程会将父线程中lnheritableThreadLocal的值复制一份到子线程的InheritableThreadLocal中,从上面代码中可以看到,父线程
             * nheritabiehreadLcal中第一次丢入的是张三,之后就调用线程池gexecute万法执行任务,比时,会在线程池中创建子线程,这个子线程会将分线程中
             * InheritableThreadLocal中设置的张三,复制到子线程的lnhertableThreadLocal中,此时子线程中的用户名就是从父线程复制过来的,即:张三
             * 复制之后,父子线程中的InheritableThreadLocal就没有关系了,父线程中|nheritableThreadLoca!的值再修改,也不会影响子线程中的值了,所以两次输出的都
             * 是张三。
             *
             * 如何解决这个问题呢?
             * 阿里的:TransmittableThreadLocal,这个就是为了解决这个问题来的。
             * 1、需要引入maven配置
             *    <dependency>
             *      <groupId>com.alibaba</groupId>
             *      <artifactId>transmittable-thread-local</artifactId>
             *      <version>2.14.3</version>
             *    </dependency>
             *  2、使用TransmittableThreadLocal 代替InherltableThreadLocal 或 ThreadLocal (TransmittapleThreadLocal<string> userNameTtl = new TransmittableThreadLocal<string>();)
             *     程池需要用TtlExecutors.getTtlExecutorService 包裹一下,这个定不要漏掉
             *     Executorservice executorservice = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(1));
             * 
             */
            log.info("userName:{}", userNameItl.get());
        }, "thread1").start();
        TimeUnit.SECONDS.sleep(1);

    }

    public static void main(String[] args) throws InterruptedException {
        new CutterOperatorScheduleJob().inheritableThreadLocal1();
    }

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值