8

我有一个关于 java 和并发的问题。

假设我有一个名为“a”的 ThreadLocal 变量。我使用 CachedThreadPool 来获取新线程。当一个线程被重用时,ThreadLocal 变量 'a' 会发生什么?它保持相同的值(因为它是同一个线程)还是开始为空(好像线程是新的)?

4

3 回答 3

11

默认情况下,ThreadLocals 与线程一起重用。如果您需要重新初始化它们,您可以通过覆盖下面提到的方法来实现:

来自 java.util.concurrent.ThreadPoolExecutor 的 javadoc

挂钩方法 此类提供受保护的可重写 beforeExecute(java.lang.Thread, java.lang.Runnable) 和 afterExecute(java.lang.Runnable, java.lang.Throwable) 方法,它们在每个任务执行之前和之后调用。这些可用于操纵执行环境;例如,重新初始化 ThreadLocals、收集统计信息或添加日志条目。此外,可以重写方法 terminate() 以执行在 Executor 完全终止后需要完成的任何特殊处理。如果钩子或回调方法抛出异常,内部工作线程可能会依次失败并突然终止。

于 2011-09-13T15:02:02.603 回答
5

您可以使用反射清除线程的线程本地池。你可以做

public static void clearAllThreadLocals() {
    try {
        Field threadLocals = Thread.class.getDeclaredField("threadLocals");
        threadLocals.setAccessible(true);
        threadLocals.set(Thread.currentThread(), null);
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}
于 2015-07-30T14:36:17.753 回答
3

如果线程返回到池中,ThreadLocal 变量仍将附加到它。将 ThreadLocals 与池一起使用时,您必须小心能够设置何时从池中拉出线程并在返回之前取消设置。

于 2011-09-13T15:01:19.407 回答