1

在重用线程池中的线程时,我们从线程的最后一次执行中获取线程局部变量值。

我知道 Thread local 是 Thread 的一部分,所以当我们使用线程池时它会被重用。但我的问题是我不想在最后一次执行中使用线程局部变量集(对很多人来说都是有效的用例)。

当线程在当前执行后进入池时,有没有更好的方法来清除线程本地值?

4

3 回答 3

3

无法使用公共 API 清除 ThreadLocals。尽管如此,ThreadPoolExecutor 有一个钩子方法,我们可以在执行前使用反射清除 Thread 中的 ThreadLocals

public class ThreadPoolExector
    protected void beforeExecute(Thread t, Runnable r) {
         ... set t.threadLocals and t.inheritableThreadLocals fields to null using reflection
    }
    ...

public class Thread
    ...
    ThreadLocal.ThreadLocalMap threadLocals;
    ThreadLocal.ThreadLocalMap inheritableThreadLocals;
    ...   
于 2013-07-26T08:15:18.443 回答
1

您可以使用反射清除线程的线程本地映射。这将清除所有线程本地变量,无论它们在哪里。

理想情况下,您应该编写代码,这样您的线程本地变量就不会像这样有状态。这意味着单元测试更加困难。

于 2013-07-26T08:04:25.820 回答
1

清除 ThreadLocal 应该是“线程用户”的责任——也就是说,放置 ThreadLocal 的代码也应该清除它。使用例如 try-finally-block 来确保发生这种情况。

但是,您可以破解您想要的内容!说真的,这并不难——你只需反省进入 Thread 对象/类的方式,找到 ThreadLocals 所在的 Map,然后清除它。

于 2013-07-26T08:06:24.997 回答