On ThreadLocal
static class ThreadLocalMap {
private Entry[] table;
int INITIAL_CAPCITY=16;
static class Entry extends WeakReference.ThreadLocal<?> {
Object value;
Entry (ThreadLocal<?> k, Object v){ //v is what the code put in
super(k); //weak ref means entry k may become null
value = v;
}
}
//on get and set, will expungeStaleEntry
}
public class Thread implements Runnable{
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
}
class ThreadLocal {
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = t.threadLocals
if(map != null)
map.set(this, value);
else
createMap(t, value);
}
}
- standard techinque to replace
% pow(2, n)
with&(pow(2,n)-1)
, and keep the size of the colleciton always2^n
- The table uses iteration to handle hash conflict, note that it will remove non-null entries whose key is null. This is part of the reason why the load factor is 2/3, lower than that of hashmap
ThreadLocal.ThreadLocalMap
is a member variable ofThread
, so we can access it with Thread.currentThread();- Weak reference to the
ThreadLocal
means that often we will haveEntry
with key = null. That is why during get() and set(), the code try to remove the stale entry. Otherwise, there is no way for outside code to break the strong reference to thevalue
object by this time. This case is a common source of memory “leak” and is also the reason it is recommended to callThreadLocal.remove()
in a finally clause after processing is done.