Класс ThreadLocal
Класс ThreadLocal создает локальную переменную потока.
Каждый поток, который обращается к такой переменной,
видит только свое собственное значение, независимо от
других потоков. Это удобно, когда нужно хранить данные,
привязанные к конкретному потоку, например, контекст
пользователя, соединение с базой данных или формат даты.
Значение задается методом set, читается методом
get и удаляется методом remove.
Если значение для потока еще не задано, метод get
возвращает null или значение, вычисленное в
переопределенном методе initialValue.
Синтаксис
ThreadLocal<Type> tl = new ThreadLocal<>();
tl.set(value);
Type value = tl.get();
tl.remove();
Пример
Давайте создадим локальную переменную потока и зададим ей значение в главном потоке:
public class Main
{
public static void main(String[] args)
{
ThreadLocal<String> tl = new ThreadLocal<>();
tl.set("abcde");
System.out.println(tl.get());
}
}
Результат выполнения кода:
"abcde"
Пример
Давайте проверим, что каждый поток видит свое значение. Зададим значение в главном потоке и запустим новый поток, который обратится к той же переменной:
public class Main
{
public static void main(String[] args) throws InterruptedException
{
ThreadLocal<String> tl = new ThreadLocal<>();
tl.set("main");
Thread thread = new Thread(() -> {
System.out.println(tl.get());
tl.set("thread");
System.out.println(tl.get());
});
thread.start();
thread.join();
System.out.println(tl.get());
}
}
Результат выполнения кода:
null
"thread"
"main"
Пример
Давайте переопределим метод initialValue,
чтобы задать значение по умолчанию для каждого потока:
public class Main
{
public static void main(String[] args) throws InterruptedException
{
ThreadLocal<Integer> tl = new ThreadLocal<>() {
@Override
protected Integer initialValue()
{
return 0;
}
};
System.out.println(tl.get());
Thread thread = new Thread(() -> {
System.out.println(tl.get());
tl.set(1);
System.out.println(tl.get());
});
thread.start();
thread.join();
System.out.println(tl.get());
}
}
Результат выполнения кода:
0
0
1
0
Пример
Давайте удалим значение переменной методом remove
и проверим результат:
public class Main
{
public static void main(String[] args)
{
ThreadLocal<String> tl = new ThreadLocal<>();
tl.set("abcde");
System.out.println(tl.get());
tl.remove();
System.out.println(tl.get());
}
}
Результат выполнения кода:
"abcde"
null