• 技术文章 >java >java基础

    java中ThreadLocal核心方法有哪些?

    小妮浅浅小妮浅浅2021-03-10 16:47:14原创1938

    1、get()方法

    (1)获取当前用的线程,并找到线程关联的threadLocalMap

    (2)threadLocalMap为空则进行初始化一个新的并返回

    (3)threadLocalMap不为空则根据threadlocal作为key查找Entry

    (4)若Entry不为空则返回entry对应的值,否则执行第二条

    public T get() {
        // 获取当前线程
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        //若当前线程关联的ThreadLocal不为空则查询
        if (map != null) {
            //根据threadLocal查询对应的Entry
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
     
     private T setInitialValue() {
         //默认返回null值
         T value = initialValue();
         Thread t = Thread.currentThread();
         ThreadLocalMap map = getMap(t);
         //如果当前调用线程关联的ThreadLocalMap为空则创建,否则设置值进去
         if (map != null)
             map.set(this, value);
         else
             //new ThreadLocalMap(this,value)
             createMap(t, value);
         return value;
     }
     
    private Entry getEntry(ThreadLocal<?> key) {
        //根据key获取其在数组的下标位置
        int i = key.threadLocalHashCode & (table.length - 1);
        Entry e = table[i];
        if (e != null && e.get() == key)
            return e;
        else
            return getEntryAfterMiss(key, i, e);
    }
     
    private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) {
        Entry[] tab = table;
        int len = tab.length;
        //数组下标的Entry不为空且关联的threadlocal与查找的threadlocal不一致
        while (e != null) {
            ThreadLocal<?> k = e.get();
            //entry关联的threadlocal与查找的相等则直接返回
            if (k == key)
                return e;
            if (k == null)
                //关联的threadlocal为空,则触发清理key为null的Entry并重新进行rehash旧Entry数组的元素
                //threadLocalMap的hash冲突与hashMap的冲突处理方式不一致,hashMap使用的是链表地址法,
                //而threadLocalMap使用的开放地址法——线性探测,即顺序查找下一位置或者遍历全表,效率较低
                expungeStaleEntry(i);
            else
                //递增下标i的值进行下一轮的查找
                i = nextIndex(i, len);
            e = tab[i];
        }
        return null;
    }

    2、remove()方法

    1)获取当前用的线程,并找到线程关联的threadLocalMap

    2)若不为空则删除threadLocalMap中关联的值,否则啥也不做

    //ThreadLocal
    public void remove() {
        ThreadLocalMap m = getMap(Thread.currentThread());
        if (m != null)
            //删除当前threadLocal对象关联的Entry
            m.remove(this);
    }
     
    //ThreadLocalMap
    private void remove(ThreadLocal<?> key) {
        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)]) {
            if (e.get() == key) {
                e.clear();
                expungeStaleEntry(i);
                return;
            }
        }
    }

    以上就是java中ThreadLocal核心方法介绍,大家会发现这些方法我们在其他的模块也有使用到。想要对其他核心方法有所了解,也可以在课后自行查阅资料。

    (本教程推荐操作环境:windows7系统、java10版,DELL G3电脑。)

    专题推荐:java threadlocal
    品易云
    上一篇:java多线程中执行多个程序 下一篇:java中ThreadLocal的应用场景分析

    相关文章推荐

    • java threadLocal源码探究

    全部评论我要评论

    © 2021 Python学习网 苏ICP备2021003149号-1

  • 取消发布评论
  • 

    Python学习网