I encoded some PoC and ran jvisualvmto actually show if static is ThreadLocalanything other than an instance ThreadLocal.
The code starts 10 different threads, each of which starts a hundred millionth loop that uses the object SimpleDateFormatstored in the field ThreadLocal.
Static ThreadLocal
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " " + dayFormat.get().format(new Date()));
for (int j = 0; j < 100000000; j++) {
dayFormat.get().format(new Date());
}
System.out.println(Thread.currentThread().getName()+" "+dayFormat.get().format(new Date()));
}).start();
}
}
private static ThreadLocal<SimpleDateFormat> dayFormat =
new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
}

There are no memory leaks, as expected.
Instance ThreadLocal
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
Main m = new Main();
System.out.println(Thread.currentThread().getName() + " " + m.dayFormat.get().format(new Date()));
for (int j = 0; j < 100000000; j++) {
m.dayFormat.get().format(new Date());
}
System.out.println(Thread.currentThread().getName()+" "+m.dayFormat.get().format(new Date()));
}).start();
}
}
private ThreadLocal<SimpleDateFormat> dayFormat =
new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
}

. ( 20%) , , .
, "" ThreadLocal , , GC .
.
ThreadLocal,
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " " + dayFormat.get().format(new Date()));
for (int j = 0; j < 100000000; j++) {
dayFormat.set(null);
dayFormat.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
dayFormat.get().format(new Date());
}
System.out.println(Thread.currentThread().getName()+" "+dayFormat.get().format(new Date()));
}).start();
}
}
private static ThreadLocal<SimpleDateFormat> dayFormat =
new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
}

ThreadLocal,
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
Main m = new Main();
System.out.println(Thread.currentThread().getName() + " " + m.dayFormat.get().format(new Date()));
for (int j = 0; j < 100000000; j++) {
m.dayFormat.set(null);
m.dayFormat.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
m.dayFormat.get().format(new Date());
}
System.out.println(Thread.currentThread().getName()+" "+m.dayFormat.get().format(new Date()));
}).start();
}
}
private ThreadLocal<SimpleDateFormat> dayFormat =
new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
}

. - GC, "" , , .
, ( 5%) .
, , , , , , ThreadLocal .