笔记

72 阅读1分钟
1.ThreadLocal
为什么要remove?

因为key 设计的是弱引用,Java的弱引用的定义是,当JVM执行垃圾回收扫描的时候,当发现只有弱引用的对象时,会立即回收此对象,这是ThreadLocal当初设计的时候防止内存溢出的一个手段。

由于 value是强引用,只要 Thread不死亡时,例如线程池,这条强引用链就会存在,那么value就不会回收,可能造成内存溢出

解决方案

但是这个消除强引用链的动作是需要业务方在get的情况下触发的,可能业务方并不会get、也可能get是key不为空,并不会触发 expungeStaleEntry 类。所以开发者要养成良好的习惯,记得用完 ThreadLocal 时,调一次ThreadLocal.remove()方法或者 ThreadLocal.set(null)

public class ThreadLocalHolder {
    private static ThreadLocal<User> userThreadLocal = new ThreadLocal<>();
 
    public static void setUserLocal(User user) {
        userThreadLocal.set(user);
    }
 
    public static void removeUserLocal() {
        userThreadLocal.set(null);
        userThreadLocal.remove();
    }
 
    public static void remove() {
        removeUserLocal();
    }
 
 
    public static void main(String[] args) throws InterruptedException {
        List<Thread> threadList = Lists.newArrayList();
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            Thread thread = new Thread(() -> {
                setUserLocal(new User("name" + finalI, "P" + finalI, Collections.singleton(new JaasGrantedAuthority("a", null))));
                System.out.println(JSON.toJSON(userThreadLocal.get()));
            });
            thread.start();
            remove();
            threadList.add(thread);
        }
        for (Thread t : threadList) {
            //等所有线程执行完成后才执行 "开始执行!!!!!!"
            t.join();
        }
        System.out.println("开始执行!!!!!!");
    }
}

链接:juejin.cn/post/709784…