当前位置:网站首页>Two problems that may occur in the use of ThreadLocal and thread pool

Two problems that may occur in the use of ThreadLocal and thread pool

2022-06-21 19:27:00 zhaozhen

Get the from the main thread or non thread pool from the direct thread pool ThreadLocal Set the value of the variable

for example

    private static final ThreadPoolExecutor syncAccessPool = new ThreadPoolExecutor(
            50,
            80,
            8000,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(600)
    );
    public static void main(String[] args) {
        ThreadLocal<String> threadLocal = new ThreadLocal<>();
        threadLocal.set("userId115807");
        syncAccessPool.execute(()->{
            System.out.println(threadLocal.get());
        });
    }

The final print is null

terms of settlement : In real use, I believe you won't use it like this , But I made a mistake mainly because I used the encapsulation method , The encapsulation method uses ThreadLocal, In this case, we should start from ThreadLocal Get the method in , Then set it to the thread pool

Used in thread pool ThreadLocal The value is set, but it is not removed after use, resulting in a surge in memory or OOM

public class ThreadLocalOOM {
    static class LocalVariable{
        private Long[] a = new Long[1024*1024];
    }
    private static final ThreadPoolExecutor syncAccessPool = new ThreadPoolExecutor(
            50,
            80,
            8000,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(600)
    );
    final static  ThreadLocal<LocalVariable> threadLocal = new ThreadLocal<LocalVariable>();


    public static void main(String[] args) throws InterruptedException {

        Thread.sleep(10000);
        for (int i=0;i<100;i++){
            syncAccessPool.execute(()->{
                threadLocal.set(new LocalVariable());
                System.out.println("use local variable");
            });
            Thread.sleep(1000);
        }
        System.out.println("pool execute over");
    }
}

This program uses jconsole The memory change observed by the program is

After use remove Subsequent memory changes

   public static void main(String[] args) throws InterruptedException {

        for (int i=0;i<100;i++){
            syncAccessPool.execute(()->{
                threadLocal.set(new LocalVariable());
                System.out.println("use local variable");
                threadLocal.remove();
            });
            Thread.sleep(1000);
        }
        System.out.println("pool execute over");
    }

Memory is several times lower than before . The reason is that there is no remove, All existing threads in the thread pool will hold this local variable , This led to a huge increase in memory . If you will private Long[] a = new Long[1024*1024]; Expansion may soon be thrown out OOM abnormal

原网站

版权声明
本文为[zhaozhen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/172/202206211749333560.html