Java ThreadLocal Deep Dive: Structure, 0x61c88647 Hash Trick & Usage
This article explains the internal architecture of Java's ThreadLocal, including its ThreadLocalMap implementation, the purpose of the special hash code 0x61c88647, collision handling strategies, proper usage patterns in web applications, and precautions for avoiding memory leaks in thread pools.
1. ThreadLocal Use Cases
In a typical web application, each user request is handled by a separate thread from a thread pool. The backend often needs to access the logged‑in user’s information in many places, and passing the request object around is cumbersome. ThreadLocal provides a convenient way to store per‑request data that can be retrieved from any code executing in the same thread.
2. ThreadLocal Principle
The Java API describes ThreadLocal as a class that supplies thread‑local variables, each thread having its own independently initialized copy. ThreadLocal instances are usually declared as private static fields.
ThreadLocal exposes four main methods: protected T initialValue() – creates and returns the initial value for the current thread. void set(T value) – stores value in the current thread’s ThreadLocal variable. T get() – retrieves the value set by set; if none exists, the initial value is returned. void remove() – removes the thread‑local variable from the current thread.
Each thread holds a ThreadLocal.ThreadLocalMap instance (named threadLocals) that stores the mappings from ThreadLocal objects to their values.
/**
* ThreadLocal values pertaining to this thread.
* This map is maintained by the ThreadLocal class.
*/
ThreadLocal.ThreadLocalMap threadLocals = null;
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
private static final int INITIAL_CAPACITY = 16;
private Entry[] table;
private Entry getEntry(ThreadLocal<?> key) { ... }
private void set(ThreadLocal<?> key, Object value) { ... }
// ... other methods ...
}Key observations:
The ThreadLocalMap instance is stored in each Thread, not in the ThreadLocal itself, so there is no global contention. When a thread dies, its map becomes eligible for garbage collection.
Each Entry’s key is a weak reference to the ThreadLocal object; if the ThreadLocal is no longer reachable, the entry can be reclaimed, preventing memory leaks.
3. Collision Resolution and the Magic 0x61c88647
3.1 Collision Avoidance and Resolution
ThreadLocalMap uses an open‑addressing linear‑probe strategy. When only one ThreadLocal instance is used, collisions arise only when multiple values are stored for that instance; they are resolved by linear probing.
When many ThreadLocal instances exist (e.g., each thread creates its own), the special hash code 0x61c88647 dramatically reduces collision probability while still using linear probing.
3.2 The Magic 0x61c88647
Each ThreadLocal object carries a field threadLocalHashCode generated by adding a constant HASH_INCREMENT = 0x61c88647 to an atomic counter. This constant is derived from the golden ratio and provides a well‑distributed multiplicative hash for power‑of‑two table sizes.
private final int threadLocalHashCode = nextHashCode();
private static AtomicInteger nextHashCode = new AtomicInteger();
private static final int HASH_INCREMENT = 0x61c88647;
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}When inserting into the map, the index is computed as key.threadLocalHashCode & (len‑1), effectively using the low bits of the hash code. Because HASH_INCREMENT is relatively prime to the table size, successive hash codes are well‑spread, minimizing clustering.
4. Using ThreadLocal with Thread Pools
Web containers such as Tomcat employ thread pools to handle requests. Since threads are reused, any ThreadLocal data left behind after a request can cause memory leaks. Therefore, it is essential to call remove() at the end of request processing to clear the thread‑local state.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
