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

猜你喜欢

转载自blog.csdn.net/u014454462/article/details/84143391