• 技术文章 >Java >java教程

    java中ThreadLocal核心方法怎么使用

    WBOYWBOY2023-04-19 18:52:07转载21

    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核心方法怎么使用的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:亿速云,如有侵犯,请联系admin@php.cn删除
    专题推荐:Java threadlocal
    上一篇:java如何使用BeanFactoryPostProcessor注入Bean 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • Java程序设计实现局域网聊天小应用的步骤• Java关键字中是否包含"default"?• 如何使用Java实现六边形架构?• 如何利用Java枚举实现单例模式?• 如何在Java中提供可供第三方使用的接口?
    1/1

    PHP中文网