The development manual explicitly recommends the use of static modifier when using ThreadLocal.
The reasons are as follows.
Principle:
Each Thread holds a ThreadLocalMap, and the key of this Map is a weak reference to ThreadLocal.
If the ThreadLocal you create is a non static member variable, it will follow the lifecycle of the external class instance.
Once the external class is reclaimed by GC and the ThreadLocal instance is not strongly referenced, it will result in:
ThreadLocal has been GCed.
Entry with null key in ThreadLocalMap leaves value unreachable but cannot be reclaimed.
If the thread is a long-term thread in the thread pool, it will cause memory leakage.
Define ThreadLocal as a static variable, making its lifecycle independent of instances of the class.
It will not cause ThreadLocal to be GCed due to external class objects being GCed, thus avoiding the situation where the key is null.
Avoid duplicate creation and improve performance
After defining ThreadLocal as static, it can be reused in multiple methods to avoid creating ThreadLocal objects multiple times and save resource costs.
private static final ThreadLocal<SimpleDateFormat> FORMATTER = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
If it's not static, every time an external class instance is created, a new ThreadLocal instance is created, which unnecessarily increases overhead and potential leaks.
ThreadLocal modified with static is generally used to store some global thread related variables (such as user information, request context, etc.)
This makes the semantics clearer, the scope clearer, and facilitates team collaboration and code maintenance
Error example
public class MyService {
// Non static, easily leading to ThreadLocal weak references being reclaimed due to GC of external classes
private ThreadLocal<Object> context = new ThreadLocal<>();
}
Correct example
public class MyService {
private static final ThreadLocal<Object> CONTEXT = new ThreadLocal<>();
}
Summary:
Reason explanation ✅ Avoid memory leaks and prevent ThreadLocal from being reclaimed, resulting in key=null and value residue ✅ Clear lifecycle: Static lifecycle is independent of object instances ✅ Improve performance, avoid duplicate creation, and increase efficiency ✅ Unified management for clearer and more maintainable code structures
So the standard recommends that ThreadLocal must be modified with static, which is the best practice for performance, security, and maintainability considerations.