线程返回线程池后是否清除ThreadLocal对象?

时间:2015-05-19 14:24:17

标签: java multithreading threadpool thread-local

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

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

4 个答案:

答案 0 :(得分:10)

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

您可以做的是一个ThreadLocal,它存储您要保留的所有状态,并在任务完成时重置该状态。您可以覆盖ThreadPoolExecutor.afterExecute(或beforeExecute)以清除ThreadLocal

来自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,而不是跟踪所有ThreadLocals。

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

答案 1 :(得分:7)

没有。作为一个原则,无论谁在本地线程中放置东西都应该负责清除它

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

答案 2 :(得分:1)

  

当线程返回ThreadPool时,执行期间存储在ThreadLocal存储中的内容是否会被自动清除

没有。 ThreadLocals与线程相关联,执行传递给线程池任务队列的Callable / Runnable。除非明确清除 - @PeterLawrey给出了一个如何执行此操作的示例 - ThreadLocals及其状态通过多个任务执行持续存在。

听起来你可以使用Callable / Runnable

中声明的局部变量来实现所需的行为

答案 3 :(得分:1)

否,ThreadLocal对象与线程关联,而不与任务关联。因此,ThreadLocal应该与线程池一起谨慎使用。作为原则,仅当线程本地生命周期与任务的生命周期一致时,线程本地才对线程池有意义。