ThreadLocal & InheritableThreadLocal 使用的一些坑

  1. ThreadLocal在与线程池结合使用时可能会出现数据复用
线程池把线程提交到队列,当被调用的时候如果存在空闲线程就回直接复用线程,仅仅是调用了用户提交线程的run方法。所以当ThreadLocal参数使用完,记得调用remove方法。
public class B {
     static final ThreadLocal<String> threadParam = new ThreadLocal<>();
     public static void main(String[] args) throws InterruptedException {
         //固定池内只有存活3个线程
         ExecutorService execService = Executors.newFixedThreadPool(3);
         //死循环几次才能看出效果
         while (true) {
             Thread t = new Thread(()->{
                     threadParam.set("abc");
                     System.out.println("t1:" + threadParam.get());
                     //如果不调用remove,将引发问题 //                    threadParam.remove();
             });
             execService.execute(t);
             TimeUnit.SECONDS.sleep(1);
             Thread t2 = new Thread(()-> {
                     System.out.println("t2:" + threadParam.get());
             });
             execService.execute(t2);
         }
     } }
  1. InheritableThreadLocal 和 线程池结合使用时会出现共享父线程的InhertiableThreadLocal
public static void main(String[] args) throws InterruptedException {
        //固定池内只有存活3个线程
        ExecutorService execService = Executors.newFixedThreadPool(3);
        //死循环几次才能看出效果
        while (true) {
            //线程1,里面有两个子线程
            Thread t = new Thread(()->{
                threadParam.set("abc");
                System.out.println("t1:" + threadParam.get());
                Thread t2 = new Thread(()->{
                    System.out.println("t2:" + threadParam.get());
//                        threadParam.remove();
                });
                execService.execute(t2);

                Thread t3 = new Thread(()->{
                    System.out.println("t3:" + threadParam.get());
//                        threadParam.remove();
                });
                execService.execute(t3);

                Thread t4 = new Thread(()->{
                    System.out.println("t4:" + threadParam.get());
//                        threadParam.remove();
                });
                execService.execute(t4);

            });
            execService.execute(t);
            TimeUnit.SECONDS.sleep(1);
            //线程4,线程1同级
            Thread t5 = new Thread(()-> {
                threadParam.set("CBA");
                System.out.println("t5:" + threadParam.get());
            });
            execService.execute(t5);
        }
    }

Another case see the below link:
https://blog.csdn.net/Sunfj0821/article/details/81349775

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值