All topics
library
advanced

ThreadLocal & InheritableThreadLocal

Store per-thread data without synchronization and understand the memory leak risk.

ThreadLocal<T> provides each thread with its own independent copy of a variable. No synchronization needed because each thread accesses only its own copy.

ThreadLocal = personal lockers at a gym. Each person (thread) has their own locker (storage). No sharing, no conflicts. But if you leave your stuff and never clean out the locker (remove), it piles up.

Key Concepts

1
Common uses: - SimpleDateFormat (not thread-safe): ThreadLocal<SimpleDateFormat> gives each thread its own formatter - User context in web applications: store the current user for the duration of a request - Database connections: per-thread connection in connection-less frameworks - Transaction context: per-thread transaction state
2
InheritableThreadLocal: child threads inherit the parent's value at creation time. Useful for propagating context (trace IDs, user info) to child threads. But the child gets a copy — changes in child don't affect parent and vice versa.
3
Memory leak risk: ThreadLocal values are stored in the thread's ThreadLocalMap. If the ThreadLocal reference is garbage collected but the thread lives on (thread pools!), the value stays in memory forever. Always call remove() in a finally block when done.
4
With virtual threads (Java 21), ThreadLocal works but is discouraged because millions of virtual threads × ThreadLocal storage = massive memory usage. Use ScopedValues instead.
5
In web applications, always use ThreadLocal with a servlet filter or interceptor that calls remove() after the request completes.