Класс ThreadLocal представляет хранилище тред-локальных переменных. По способу использования он похож на обычную обертку над значением, с методами get(), set() и remove() для доступа к нему, и дополнительным фабричным методом ThreadLocal.withInitial(), устанавливающим значение по-умолчанию.

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

Проще говоря, объект класса ThreadLocal хранит внутри не одно значение, а как бы хэш-таблицу поток➝значение, и при использовании обращается к значению для текущего потока.

Первый, самый очевидный вариант использования – данные, относящиеся непосредственно к треду, определенный пользователем «контекст потока». На скриншоте ниже пример такого использования: ThreadId.get() вернет порядковый номер текущего треда.

Другой случай, с которым локальная переменная потока может помочь – кэширование read-only данных в многопоточной среде без дорогостоящей синхронизации.

Помимо обычного ThreadLocal, в стандартной библиотеке присутствует его расширение InheritableThreadLocal. Этот класс «наследует» значение – изначально берет его для потока, являющегося родителем текущего.