👩💻 Что такое ThreadLocal.withInitial() и зачем он нужен?
Это статический метод для создания ThreadLocal переменной с фабрикой начального значения. Каждый поток получает свою собственную копию объекта, а withInitial задаёт ленивый способ её создания — при первом вызове get().
⚡️ Пример:
import java.text.SimpleDateFormat;
import java.util.concurrent.*;
public class ThreadLocalExample {
// Безопасный форматтер без синхронизации
private static final ThreadLocal dateFormat =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
public static void main(String[] args) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 5; i++) {
final int taskId = i;
pool.submit(() -> {
String formatted = dateFormat.get().format(new java.util.Date());
System.out.println(Thread.currentThread().getName() + " -> " + formatted + " (task " + taskId + ")");
});
}
pool.shutdown();
}
}
➡️ Easy Java | #Теория
Это статический метод для создания ThreadLocal переменной с фабрикой начального значения. Каждый поток получает свою собственную копию объекта, а withInitial задаёт ленивый способ её создания — при первом вызове get().
⚡️ Пример:
import java.text.SimpleDateFormat;
import java.util.concurrent.*;
public class ThreadLocalExample {
// Безопасный форматтер без синхронизации
private static final ThreadLocal dateFormat =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
public static void main(String[] args) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 5; i++) {
final int taskId = i;
pool.submit(() -> {
String formatted = dateFormat.get().format(new java.util.Date());
System.out.println(Thread.currentThread().getName() + " -> " + formatted + " (task " + taskId + ")");
});
}
pool.shutdown();
}
}
Особенно полезен при хранении не потокобезопасных объектов (SimpleDateFormat, Random), изоляции пользовательской сессии/токена в вебе, переиспользовании тяжелых ресурсов без синхронизации.
➡️ Easy Java | #Теория