线程返回到线程池后,ThreadLocal对象是否会被清除?



在执行期间存储在ThreadLocal存储中的内容是否会在线程返回到ThreadPool时自动清除(如预期的那样)?

在我的应用程序中,我在一些执行期间将一些数据放在ThreadLocal中,但如果下一次使用相同的线程,那么我将在ThreadLocal存储中找到过时的数据。

除非你这样做,否则ThreadLocal和ThreadPool不会相互作用。

你可以做的是一个单独的ThreadLocal,它存储所有你想要持有的状态,并在任务完成时重置。你可以重写ThreadPoolExecutor。afterExecute(或beforeExecute)清除ThreadLocal(s)

从ThreadPoolExecutor

/**
 * Method invoked upon completion of execution of the given Runnable.
 * This method is invoked by the thread that executed the task. If
 * non-null, the Throwable is the uncaught {@code RuntimeException}
 * or {@code Error} that caused execution to terminate abruptly.
 *
 * <p>This implementation does nothing, but may be customized in
 * subclasses. Note: To properly nest multiple overridings, subclasses
 * should generally invoke {@code super.afterExecute} at the
 * beginning of this method.
 *
... some deleted ...
 *
 * @param r the runnable that has completed
 * @param t the exception that caused termination, or null if
 * execution completed normally
 */
protected void afterExecute(Runnable r, Throwable t) { }

与其跟踪所有的ThreadLocals,不如一次清除它们。

protected void afterExecute(Runnable r, Throwable t) { 
    // you need to set this field via reflection.
    Thread.currentThread().threadLocals = null;
}

No。作为一个原则,无论谁在线程本地放了什么东西,都应该负责清除它

threadLocal.set(...);
try {
  ...
} finally {
  threadLocal.remove();
}

在执行过程中存储在ThreadLocal存储中的内容是否会在线程返回到ThreadPool时自动清除

。ThreadLocals与线程相关联,不是与Callable/Runnable传递给线程池任务队列的执行相关联。除非显式清除——@PeterLawrey给出了一个如何这样做的例子——ThreadLocals和它们的状态会在多个任务执行中持续存在。

听起来你可以通过在Callable/Runnable

中声明一个局部变量来实现期望的行为

不,ThreadLocal对象关联到线程而不是任务。因此,ThreadLocal应该小心地与线程池一起使用。作为一个原则,只有当线程局部生命周期与任务

的生命周期一致时,线程池才有意义。

最新更新