Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

//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;
    }
}