ThreadLocal
— класс, позволяющий имея одну переменную, иметь различное её значение для каждого из потоков.
У каждого потока — т.е. экземпляра класса Thread
— есть ассоциированная с ним таблица ThreadLocal-переменных. Ключами таблицы являются cсылки на объекты класса ThreadLocal
, а значениями — ссылки на объекты, «захваченные» ThreadLocal-переменными, т.е. ThreadLocal-переменные отличаются от обычных переменных тем, что у каждого потока свой собственный, индивидуально инициализируемый экземпляр переменной. Доступ к значению можно получить через методы get()
или set()
.
Например, если мы объявим ThreadLocal-переменную: ThreadLocal<Object> locals = new ThreadLocal<Object>();
. А затем, в потоке, сделаем locals.set(myObject)
, то ключом таблицы будет ссылка на объект locals
, а значением — ссылка на объект myObject
. При этом для другого потока существует возможность «положить» внутрь locals
другое значение.
Следует обратить внимание, что ThreadLocal
изолирует именно ссылки на объекты, а не сами объекты. Если изолированные внутри потоков ссылки ведут на один и тот же объект, то возможны коллизии.
Так же важно отметить, что т.к. ThreadLocal-переменные изолированы в потоках, то инициализация такой переменной должна происходить в том же потоке, в котором она будет использоваться. Ошибкой является инициализация такой переменной (вызов метода set()
) в главном потоке приложения, потому как в данном случае значение, переданное в методе set()
, будет «захвачено» для главного потока, и при вызове метода get()
в целевом потоке будет возвращен null
.