How to clean up ThreadLocals

前端 未结 7 1687
遇见更好的自我
遇见更好的自我 2020-11-28 23:01

Does any one have an example how to do this? Are they handled by the garbage collector? I\'m using Tomcat 6.

7条回答
  •  攒了一身酷
    2020-11-28 23:40

    Here is some code to clean all thread local variables from the current thread when you do not have a reference to the actual thread local variable. You can also generalize it to cleanup thread local variables for other threads:

        private void cleanThreadLocals() {
            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) {
                // We will tolerate an exception here and just log it
                throw new IllegalStateException(e);
            }
        }
    

提交回复
热议问题