Я читал здесь JavaDoc для Threadlocal
https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ThreadLocal.html
и говорится: «Экземпляры ThreadLocal обычно представляют собой частные статические поля в классах, которые хотят связать состояние с потоком (например, ID пользователя или ID транзакции)».
Но у меня вопрос: почему они решили сделать его статическим (как правило) - это немного сбивает с толку наличие состояния «на поток», но поля статические?
источник
ThreadLocal
для хранения ссылки на хэш-набор, который сопоставляет объекты с экземплярами потока.ThreadLocal
будет содержать свои собственные локальные данные потока, даже если этиThreadLocal
экземпляры существуют в одном потоке. Это не обязательно неправильно - я полагаю, что это может быть наименее популярный шаблон из двухЛибо сделайте его статическим, либо, если вы пытаетесь избежать каких-либо статических полей в своем классе, сделайте сам класс синглтоном, а затем вы можете безопасно использовать уровень экземпляра ThreadLocal, если этот синглтон доступен глобально.
источник
Так не должно быть. Важно то, что это должен быть синглтон.
источник
Причина в том, что доступ к переменным осуществляется через указатель, связанный с потоком. Они действуют как глобальные переменные с областью видимости потока, поэтому статические значения лучше всего подходят. Таким образом вы получаете локальное состояние потока в таких вещах, как pthreads, так что это может быть просто случайностью истории и реализации.
источник
Использование threadlocal для каждого экземпляра на поток - это если вы хотите, чтобы что-то было видимым во всех методах объекта и чтобы это было потокобезопасным без синхронизации доступа к нему, как если бы вы это делали для обычного поля.
источник
Обратитесь к этому , это даст лучшее понимание.
Короче говоря,
ThreadLocal
объект работает как карта "ключ-значение". Когда поток вызываетThreadLocal
get/set
метод, он извлекает / сохраняет объект потока в ключе карты и значение в значении карты. Вот почему разные потоки имеют разное скопированное значение (которое вы хотите сохранить локально), потому что оно находится в другой записи карты.Вот почему вам нужна только одна карта для хранения всех значений. Хотя это и не обязательно, у вас может быть несколько карт (без объявления static) для хранения каждого объекта потока, что полностью избыточно, поэтому предпочтительнее статическая переменная.
источник
static final ThreadLocal
переменные потокобезопасны.static
делает переменную ThreadLocal доступной в нескольких классах только для соответствующего потока. это своего рода разделение глобальных переменных на соответствующие локальные переменные потока в нескольких классах.Мы можем проверить безопасность этого потока с помощью следующего примера кода.
CurrentUser
- сохраняет текущий идентификатор пользователя в ThreadLocalTestService
- Простой сервис с методом -getUser()
получить текущего пользователя из CurrentUser.TestThread
- этот класс используется для создания нескольких потоков и одновременной установки идентификаторов пользователей.
.
.
Запустите основной класс TestThread. Вывод -
Резюме анализа
main
выполнение завершается и вывод текущего пользователя как «62», параллельноеForkJoinPool.commonPool-worker-1
выполнение завершается и вывод текущего пользователя как «87», параллельноеForkJoinPool.commonPool-worker-2
выполнение завершается и вывод текущего пользователя как «31», параллельноеForkJoinPool.commonPool-worker-3
выполнение завершается и вывод текущего пользователя как «81»Вывод
Параллельные потоки могут получать правильные идентификаторы пользователей, даже если они объявлены как "static final ThreadLocal"
источник