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

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

在我的应用程序中,我在执行期间放入了一些数据,但是如果下次使用相同的线程,那么我在存储中发现了过时的数据。ThreadLocalThreadLocal


答案 1

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) { }

与其跟踪所有 ThreadLocal,不如一次清除所有 ThreadLocal。

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

答案 2

不。原则上,无论谁在线程本地放置某些内容,都应该负责清除它

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