ThreadLocal
– переменная ПОТОКА. Это не переменная объекта потока, а именно переменная ПОТОКА. То есть она принадлежит только одному потоку и существует только в одном потоке.
В примере ниже мы создаем объект потока threadDemo
, который передаем на выполнение в три потока. То есть три потока будут работать с одним и тем же объектом.
Если переменная НЕ ThreadLocal и эта переменная в этом объекте меняется каким-то одним потоком, то эта переменная будет измененной и в других потоках, так как они работают с одним и тем же объектом.
Но ThreadLocal переменная не такая. Если ThreadLocal переменную в объекте изменит какой-то один поток, то она не будет измененной в других потоках не смотря на то, что они работают с одним объектом. Она будет измененной только в потоке, который ее изменил.
Пример программы:
Вывод:

Как можно увидеть в консоли, переменную counter
меняли все три потока, а переменная threadLocalCounter
была у каждого потока своя личная и в каждом из потоков она только успела стать 0.
Как можно увидеть ThreadLocal иногда не заменим, например в этом случае, когда создать локальную переменную для потока можно только с помощью ThreadLocal, потому что объект один, это threadDemo и все потоки работают с ним, и соответственно, например, локальная переменная counter для всех потоков общая и все потоки изменяют ее в этом объекте, а чтобы создать личную для каждого потока работающего с объектом threadDemo необходимо использовать ThreadLocal.
То есть counter – переменная объекта, threadLocalCounter – переменная потока.
ThreadLocal и потоконебезопасные обьекты
Одним из важных применений ThreadLocal
является работа с потокоНЕбезопасными объектами.
Объекты некоторых классов (например SimpleDateFormat
) потокоНЕбезопасны.
То есть если к одному и тому же объекту SimpleDateFormat
одновременно обращаются несколько потоков, то нужно применять синхронизацию в потоках (используя synchronized например), иначе будет ошибка. Но синхр-я тормозит работу программы. Поможет ThreadLocal.
То есть если объект реализует Runnable, и он будет использоваться многими потоками, и в этом объекте есть потокоНЕбезопасный объект, лучше не использовать синхронизацию, а размножить его на все потоки используя ThreadLocal.
То есть с помощью ThreadLocal можно сделать так, что у каждого потока будет свой объект SimpleDateFormat.
Fork/Join framework в Java
Fork/Join Framework в Java: разбивайте задачи на подзадачи для параллельного выполнения. Пример использования RecursiveTask и оптимизация многопоточных вычислений.
Что такое сериализация в Java
Узнайте, как работает сериализация в Java: сохраняйте объекты в файлы с ObjectOutputStream и восстанавливайте их через ObjectInputStream. Пример кода и важность интерфейса Serializable.
Transient в Java
Ключевое слово transient в Java: как исключить поля из сериализации. Практическое руководство по работе с несериализуемыми данными.