Будет ли очищен объект ThreadLocal после возврата потока в пул потоков?

Будет ли автоматически очищаться содержимое, которое хранится в хранилище ThreadLocal во время выполнения, когда поток возвращается в ThreadPool (как и следовало ожидать) ??

В моем приложении я помещаю некоторые данные в ThreadLocal во время некоторого выполнения, но если в следующий раз будет использоваться тот же поток, то я нахожу устаревшие данные в ThreadLocal хранилище.


person Rahul Vedpathak    schedule 19.05.2015    source источник
comment
Разве вы не отвечаете на свой вопрос? Вы говорите: если используется один и тот же поток, значит, я нахожу устаревшие данные. Итак, в чем тогда ваш вопрос?   -  person GhostCat    schedule 19.05.2015


Ответы (4)


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, вы можете очистить их все сразу.

protected void afterExecute(Runnable r, Throwable t) { 
    // you need to set this field via reflection.
    Thread.currentThread().threadLocals = null;
}
person Peter Lawrey    schedule 19.05.2015
comment
чувак ... а что, если ThreadPoolExecutor использует какие-то локальные переменные потока. - person ZhongYu; 19.05.2015

Нет. Как правило, тот, кто помещает что-то в локальный поток, должен нести ответственность за его удаление.

threadLocal.set(...);
try {
  ...
} finally {
  threadLocal.remove();
}
person ZhongYu    schedule 19.05.2015

Будет ли автоматически очищаться содержимое, которое хранится в хранилище ThreadLocal во время выполнения, когда поток возвращается в ThreadPool

Нет. ThreadLocals связаны с потоками, не с выполнением Callable / Runnable, передаваемого в очередь задач пула потоков. Если явно не очищено - @PeterLawrey дает пример того, как это сделать - ThreadLocals и их состояние сохраняются при выполнении нескольких задач.

Похоже, вы можете добиться желаемого поведения с помощью локальной переменной, объявленной в вашем Callable / Runnable

person JMess    schedule 24.04.2018

Нет, объект ThreadLocal связан с потоком, а не с задачей. Следовательно, ThreadLocal следует использовать с пулом потоков с осторожностью. В принципе, локальный поток имеет смысл с пулом потоков только тогда, когда локальный жизненный цикл потока совпадает с жизненным циклом задачи.

person Hitesh    schedule 15.01.2020