分享

threadlocal

 忠波irlphwt1ng 2020-02-24

大纲:

  1. 用法

  2. 源码

一、用法

ThreadLocal是一个容器,顾名思义就是把一个变量存到线程本地。

复制代码
class Test {public static void main(String[] args)  {new Thread(new TestLocal()).start();new Thread(new TestLocal()).start();new Thread(new TestLocal()).start();
    }
}class TestLocal implements Runnable {
    ThreadLocal<String> localName = new ThreadLocal<>();

    @Overridepublic void run() {
        localName.set(Thread.currentThread().getName());
        System.out.println(localName.get());
    }
}/**结果:
 * Thread-0
 * Thread-1
 * Thread-2 */
复制代码

二、源码

ThreadLocal是线程本地变量,因此每个Thread对象内部必然存储ThreadLocal,ThreadLocal作为key,存储在ThreadLocalMap中。

class Thread {
    ThreadLocal.ThreadLocalMap threadLocals = null; //每个线程对象内部维护了一个ThreadLocal.ThreadLocalMap。...
}

ThreadLocal主要方法就是set,get

  • set:

复制代码
public class ThreadLocal<T> {static class ThreadLocalMap {...} //ThreadLocalMap是ThreadLocal的静态内部类...public void set(T value) {
        Thread t = Thread.currentThread(); //拿到当前线程ThreadLocalMap map = getMap(t); //取出线程维护的ThreadLocalMapif (map != null)
            map.set(this, value); //ThreadLocalMap的key为当前ThreadLocal对象,value就是我们需要存储的变量elsecreateMap(t, value); //该线程第一次使用ThreadLocal.set时创建ThreadLocalMap对象,并赋值。}void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

    ThreadLocalMap getMap(Thread t) {return t.threadLocals;
    }

  ... }
复制代码
  • get:

复制代码
public class ThreadLocal<T> {public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t); //从当前线程取出ThreadLocalMapif (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this); //以当前ThreadLocal对象为key取出ThreadLocalMap.Entryif (e != null) {
                T result = (T)e.value;return result;
            }
        }return setInitialValue(); //如果这个ThreadLocal对象没有赋值直接get,会给它赋值为null并返回。}private T setInitialValue() {
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);if (map != null)
            map.set(this, value);elsecreateMap(t, value);return value;
    }protected T initialValue() {return null;
    }

  ... }
复制代码

ThreadLocal get、set思想小结:

  1. 拿到当前线程对象。

  2. 拿到线程对象内部维护的ThreadLocalMap对象。

  3. 一个线程对象中只有一个ThreadLocalMap对象,所有ThreadLocal对象及这个ThreadLocal对象存储的值都以key-value的形式存在ThreadLocalMap中。(ThreadLocalMap的key是ThreadLocal对象,value是需要存储的变量。)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多