栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ThreadLocal的部分分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ThreadLocal的部分分析

ThreadLocal是为了实现在一个线程中可以在不同阶段访问同一个数据,同时隔离其他线程,不同于普通全局变量,可能会有不同的线程访问同一个全局变量,导致数据的不安全

ThreadLocal是利用一个线程维护一个ThreadLocalMap,

ThreadLocal.ThreadLocalMap threadLocals = null;

ThreadlocalMap是Thread的Threadlocals属性进行存放,当一个线程销毁时ThreadLocal也会随着销毁

早于JDK1.8时,是通过ThreadLocal进行对ThreadLocalMap的维护,但是ThreadLocal若是在Web项目中是服务器关闭后才会销毁,那么ThreadLocalMap会存在很长一段时间,当过多的时候会占用太多内存

另外一点不同之处是1.8之前Entry中的key是Thread,后来是ThreadLocal,首先知道ThreadLocal set和get存取数据时是通过

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

来确定该Entry在数组中的index,如果key是Thread,那么会导致一个线程只能有一个Entry,Entry[]能存的数据就会很少

ThreadLocalMap和Entry都是ThreadLocal的静态内部类

Entry[] table是ThreadLocalMap的属性

他们之间的逻辑关系是一个线程维护一个threadLocalMap,其中的table数组存储一个线程的不同threadLocal

static class Entry extends WeakReference> {
            
            Object value;

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

Entry继承的是弱引用,他的Key即是弱引用,value还是强引用,在remove时会将key=null,然后在每次set和get时会将key值没null的value清除。

public void clear() {
        this.referent = null;
    }

referent即是key

set()

public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            map.set(this, value);
        } else {
            createMap(t, value);
        }
    }

map.set()

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()

public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }





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




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);
        }
        if (this instanceof TerminatingThreadLocal) {
            TerminatingThreadLocal.register((TerminatingThreadLocal) this);
        }
        return value;
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/271142.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号