Java tutorial
//package com.java2s; //License from project: Apache License import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Main { /** * Sets the current thread's copy of this thread-local variable * to the specified value. Most subclasses will have no need to * override this method, relying solely on the {@link #initialValue} * method to set the values of thread-locals. * * @param value the value to be stored in the current thread's copy of * this thread-local. * @throws IllegalAccessException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws SecurityException * @throws NoSuchMethodException * @throws InvocationTargetException */ public static <T extends Object> void set(Thread thread, ThreadLocal<T> threadLocal, T value) throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { //ThreadLocalMap map = getMap(t); Object map = getMap(thread); if (map != null) { //map.set(this, value); Method setMethod = map.getClass().getDeclaredMethod("set", new Class<?>[] { ThreadLocal.class, Object.class }); setMethod.setAccessible(true); setMethod.invoke(map, new Object[] { threadLocal, value }); } else createMap(thread, threadLocal, value); } /** * Returns a reference to the thread's threadLocals field * * @param t * @return * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException */ private static Object getMap(Thread t) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field threadLocalField = Thread.class.getDeclaredField("threadLocals"); threadLocalField.setAccessible(true); return threadLocalField.get(t); } /** * * @param <T> * @param thread * @param threadLocal * @param value * @throws NoSuchMethodException * @throws IllegalAccessException * @throws InvocationTargetException */ private static <T extends Object> void createMap(Thread thread, ThreadLocal<T> threadLocal, T value) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Method createMapMethod = ThreadLocal.class.getDeclaredMethod("createMap", new Class<?>[] { Thread.class, Object.class }); createMapMethod.setAccessible(true); createMapMethod.invoke(threadLocal, new Object[] { thread, value }); } /** * Returns the value in the current thread's copy of this * thread-local variable. If the variable has no value for the * current thread, it is first initialized to the value returned * by an invocation of the {@link #initialValue} method. * * @return the current thread's value of this thread-local * @throws NoSuchMethodException * @throws SecurityException * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException */ @SuppressWarnings("unchecked") public static <T extends Object> T get(Thread thread, ThreadLocal<T> threadLocal) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchFieldException { Object map = getMap(thread); // ThreadLocalMap if (map != null) { // calling getEntry returns a ThreadLocal.Entry instance, which is a // mapping from a ThreadLocal to an Entry, and an Entry is an // extension of WeakReference. // ThreadLocalMap.Entry e = map.getEntry(this); Method getEntryMethod = map.getClass().getDeclaredMethod("getEntry", new Class[] { ThreadLocal.class }); getEntryMethod.setAccessible(true); Object entry = getEntryMethod.invoke(map, new Object[] { threadLocal }); // ThreadLocalMap.Entry if (entry != null) { Field valueField = entry.getClass().getDeclaredField("value"); valueField.setAccessible(true); return (T) valueField.get(entry); } } return setInitialValue(thread, threadLocal); } /** * Variant of set() to establish initialValue. Used instead * of set() in case user has overridden the set() method. * * @return the initial value * @throws NoSuchMethodException * @throws SecurityException * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException */ @SuppressWarnings("unchecked") private static <T extends Object> T setInitialValue(Thread thread, ThreadLocal<T> threadLocal) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchFieldException { T value = null; // value = threadLocal.initialValue(); Method initialValueMethod = ThreadLocal.class.getDeclaredMethod("initialValue", (Class<?>[]) null); initialValueMethod.setAccessible(true); value = (T) initialValueMethod.invoke(threadLocal, (Object[]) null); Object map = getMap(thread); if (map != null) { // map.set(this, value); Method setMethod = map.getClass().getDeclaredMethod("set", new Class<?>[] { ThreadLocal.class, Object.class }); setMethod.setAccessible(true); setMethod.invoke(map, new Object[] { threadLocal, value }); } else { //createMap(t, value); createMap(thread, threadLocal, value); } return value; } }