Автор оригинала: Pankaj Kumar.
Java ThreadLocal используется для создания локальных переменных потока. Мы знаем, что все потоки объекта совместно используют его переменные, поэтому переменная не является потокобезопасной. Мы можем использовать синхронизацию для обеспечения потокобезопасности, но если мы хотим избежать синхронизации, мы можем использовать переменные ThreadLocal
.
Java ThreadLocal
У каждого потока есть своя собственная переменная ThreadLocal
, и они могут использовать методы get() и set (), чтобы получить значение по умолчанию или изменить его значение локально для потока.
Экземпляры ThreadLocal обычно являются частными статическими полями в классах, которые хотят связать состояние с потоком.
Пример Java ThreadLocal
Вот небольшой пример, показывающий использование ThreadLocal в java-программе и доказывающий, что каждый поток имеет свою собственную копию переменной ThreadLocal.
Вот небольшой пример, показывающий использование ThreadLocal в java-программе и доказывающий, что каждый поток имеет свою собственную копию переменной ThreadLocal.
package com.journaldev.threads; import java.text.SimpleDateFormat; import java.util.Random; public class ThreadLocalExample implements Runnable{ // SimpleDateFormat is not thread-safe, so give one to each thread private static final ThreadLocalformatter = new ThreadLocal (){ @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyyMMdd HHmm"); } }; public static void main(String[] args) throws InterruptedException { ThreadLocalExample obj = new ThreadLocalExample(); for(int i=0 ; i<10; i++){ Thread t = new Thread(obj, ""+i); Thread.sleep(new Random().nextInt(1000)); t.start(); } } @Override public void run() { System.out.println("Thread Name= "+Thread.currentThread().getName()+" default Formatter = "+formatter.get().toPattern()); try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } //formatter pattern is changed here by thread, but it won't reflect to other threads formatter.set(new SimpleDateFormat()); System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern()); } }
Результатом приведенного выше примера программы java ThreadLocal является:
Thread Name= 0 default Formatter = yyyyMMdd HHmm Thread Name= 1 default Formatter = yyyyMMdd HHmm Thread Name= 0 formatter = M/d/yy h:mm a Thread Name= 2 default Formatter = yyyyMMdd HHmm Thread Name= 1 formatter = M/d/yy h:mm a Thread Name= 3 default Formatter = yyyyMMdd HHmm Thread Name= 4 default Formatter = yyyyMMdd HHmm Thread Name= 4 formatter = M/d/yy h:mm a Thread Name= 5 default Formatter = yyyyMMdd HHmm Thread Name= 2 formatter = M/d/yy h:mm a Thread Name= 3 formatter = M/d/yy h:mm a Thread Name= 6 default Formatter = yyyyMMdd HHmm Thread Name= 5 formatter = M/d/yy h:mm a Thread Name= 6 formatter = M/d/yy h:mm a Thread Name= 7 default Formatter = yyyyMMdd HHmm Thread Name= 8 default Formatter = yyyyMMdd HHmm Thread Name= 8 formatter = M/d/yy h:mm a Thread Name= 7 formatter = M/d/yy h:mm a Thread Name= 9 default Formatter = yyyyMMdd HHmm Thread Name= 9 formatter = M/d/yy h:mm a
Как вы можете видеть из выходных данных, Thread-0 изменил значение форматирования, но по-прежнему форматирование по умолчанию thread-2 совпадает с инициализированным значением. Вы можете увидеть тот же шаблон и для других потоков.
Обновление : Класс ThreadLocal расширен в Java 8 с помощью нового метода с Initial ()
, который принимает в качестве аргумента функциональный интерфейс поставщика. Таким образом, мы можем использовать лямбда-выражения для простого создания экземпляра ThreadLocal. Например, приведенная выше локальная переменная форматирования может быть определена в одной строке, как показано ниже:
private static final ThreadLocalformatter = ThreadLocal. withInitial (() -> {return new SimpleDateFormat("yyyyMMdd HHmm");});
Если вы новичок в функциях Java 8, пожалуйста, ознакомьтесь с функциями Java 8 и функциональными интерфейсами Java 8 .
Это все для ThreadLocal в программировании на java.
Ссылка: API Doc