前言
自从上次TransmittableThreadLocal框架作者评论我之后,我重新去看了下源码,终于在这个周天,我才把TransmittableThreadLocal解决线程池变量丢失的问题搞明白,而且发现我之前的认识有问题,久久孩子
我之前是觉得,InheritableThreadLocal解决父子线程变量传递的问题,这个没有毛病,主要是TransmittableThreadLocal解决线程池变量丢失问题,我一直以为是拿不到父线程的本地变量的,结果打脸了,因为线程池第一批子线程是main线程创建出来的,属于父子线程。
最关键的问题是,线程池会复用之前的线程,导致父线程的本地变量更新之后,之前创建的子线程拿不到这个值。
那么我们去看下它是怎么解决的~
InheritableThreadLocal缺陷
线程池第一批线程能否拿到父线程变量?
我们通过一个demo来试下
ThreadPoolExecutor executor = new ThreadPoolExecutor(1,1,1, TimeUnit.MINUTES,new ArrayBlockingQueue<>(1));
ThreadLocal local = new InheritableThreadLocal();
local.set(1);
executor.execute(()->{
System.out.println("打印1:"+local.get());
});
复制代码
打印是1,ThreadLocal get方法拿的是当前线程里面map来找值,既然子线程里头能找到父线程的值,说明第一批线程池创建的子线程是会被复制父线程的变量的,也就是InheritableThreadLocal的功劳
那么InheritableThreadLocal的缺陷在哪里?
它的缺陷其实就是TransmittableThreadLocal要去解决的。主要问题是线程池的线程复用,池化技术大家都听过吧,没有听过过来挨打。就是把连接热乎了,不用每次都去拿