性能问答>这个 ThreadLocal 怎么防止类加载器被回收?>
2回复

这个 ThreadLocal 怎么防止类加载器被回收?



我想搞清楚 Threadlocal是怎样导致类加载器泄漏的,所以写了这些代码

public class Main {
    public static void main(String... args) throws Exception {
        loadClass();
        while (true) {
            System.gc();
            Thread.sleep(1000);
        }
    }

    private static void loadClass() throws Exception {
        URL url = Main.class.getProtectionDomain()
                .getCodeSource()
                .getLocation();
        MyCustomClassLoader cl = new MyCustomClassLoader(url);
        Class<?> clazz = cl.loadClass("com.test.Foo");
        clazz.newInstance();
        cl = null;
    }
}

class MyCustomClassLoader extends URLClassLoader {
    public MyCustomClassLoader(URL... urls) {
        super(urls, null);
    }

    @Override
    protected void finalize() {
        System.out.println("*** CustomClassLoader finalized!");
    }
}

Foo.java

public class Foo {
    private static final ThreadLocal<Bar> tl = new ThreadLocal<Bar>();

    public Foo() {
        Bar bar = new Bar();
        tl.set(bar);
        System.out.println("Test ClassLoader: " + this.getClass()
                .getClassLoader());
    }

    @Override
    protected void finalize() {
        System.out.println(this + " finalized!");
    }
}

Bar.java

public class Bar {
    public Bar() {
        System.out.println(this + " created");
        System.out.println("Bar ClassLoader: " + this.getClass()
                .getClassLoader());
    }

    @Override
    public void finalize() {
        System.out.println(this + " finalized");
    }
}

我运行代码后,它显示未调用 MyCustomClassloader 和 Bar finalize,仅调用 Foo finalize。 但我把 Threadlocal 更改为 String 时,所有的 finalize 都会被调用。

public class Foo {
    private static final ThreadLocal<String> tl = new ThreadLocal<String>();

    public Foo() {
        Bar bar = new Bar();
        tl.set("some");
        System.out.println("Test ClassLoader: " + this.getClass()
                .getClassLoader());
    }

有大佬能解释一下为什么在使用 ThreadLocal 作为 String 和 Bar 的时候会有区别吗?

1536 阅读
请先登录,查看2条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步