Skip to content

Instantly share code, notes, and snippets.

@serkan-ozal
Created February 8, 2015 11:54
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save serkan-ozal/b6a9701801279736e5ec to your computer and use it in GitHub Desktop.
Save serkan-ozal/b6a9701801279736e5ec to your computer and use it in GitHub Desktop.
A Hacky Way to Clean All Thread Local Variables of Current Thread
void cleanThreadLocalsOfCurrentThread() {
try {
// Get a reference to the thread locals table of the current thread
Thread thread = Thread.currentThread();
Field threadLocalsField = Thread.class.getDeclaredField("threadLocals");
threadLocalsField.setAccessible(true);
Object threadLocalTable = threadLocalsField.get(thread);
// Get a reference to the array holding the thread local variables inside the
// ThreadLocalMap of the current thread
Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
Field tableField = threadLocalMapClass.getDeclaredField("table");
tableField.setAccessible(true);
Object table = tableField.get(threadLocalTable);
// The key to the ThreadLocalMap is a WeakReference object. The referent field of this object
// is a reference to the actual ThreadLocal variable
Field referentField = Reference.class.getDeclaredField("referent");
referentField.setAccessible(true);
for (int i = 0; i < Array.getLength(table); i++) {
// Each entry in the table array of ThreadLocalMap is an Entry object
// representing the thread local reference and its value
Object entry = Array.get(table, i);
if (entry != null) {
// Get a reference to the thread local object and remove it from the table
ThreadLocal threadLocal = (ThreadLocal) referentField.get(entry);
threadLocal.remove();
}
}
} catch(Exception e) {
// No way to handle, just throw it
throw new IllegalStateException(e);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment