Read the ThreadLocal source code

// can access thread local variables

// first look at the constructor
public ThreadLocal() {
    }

//Settings
public void set(T value) {
        Thread t = Thread.currentThread();
	//This Map uses this as the key
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

//Inheriting WeakReference indicates that this key is automatically recycled
static class ThreadLocalMap {
        static class Entry extends WeakReference<ThreadLocal> {
           
            Object value;

            Entry(ThreadLocal k, Object v) {
                super(k);
                value = v;
            }
        }

private void set(ThreadLocal key, Object value) {

            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);

            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) {
                ThreadLocal k = e.get();

                if (k == key) {
                    e.value = value;
                    return;
                }

                if (k == null) {
                    replaceStaleEntry(key, value, i);
                    return;
                }
            }

            tab[i] = new Entry(key, value);
            int sz = ++size;
            if (!cleanSomeSlots(i, sz) && sz >= threshold)
                rehash();
        }

// get the saved value
public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);

        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
	    // return if there is a value
            if (e != null)
                return (T)e.value;
        }
	//return the initialized value
        return setInitialValue();
    }

//set the initialized value
private T setInitialValue() {
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }

//Override this method to get the initial value
protected T initialValue() {
        return null;
    }

// delete value
 public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }


/**
Summary: ThreadLocal is mainly used to pass variables. If you want to set the initialized value, you can directly override the initialValue() method.
The principle is: store the value in a ThreadLocalMap. Take itself as the key and the value as the value. This map inherits WeakReference.
Indicates that it is a weak reference to the key (equivalent to WeakHashMap).
*/

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326457067&siteId=291194637