ThreadLocal解析

这篇博客详细解析了ThreadLocal,从其基本概念到核心方法,包括get()、set()、remove(),并探讨了ThreadLocalMap的实现和解决hash冲突的策略,帮助读者深入理解线程局部变量的工作原理。

一、 ThreadLocal是什么

ThreadLocal,即线程变量,是一个以ThreadLocal对象为键,任意对象为值的存储结构。这个结构被附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值。(注意:一个线程可以存放多个ThreadLocal对象。)

二、 ThreadLocal类的核心方法

ThreadLocal类提供了以下几个核心方法:

  1. get():获取当前线程的变量值
  2. set(T value):设置当前线程的变量值
  3. remove():移除当前线程的变量值
  4. initialValue():初始化当前线程的变量值

三、 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();
    }

根据代码可以看出,get()方法首先判断ThreadLocalMap是否存在,如果存在的话,寻找当前ThreadLocal变量所在位置,如果找到,则取出相应的值并返回。那么现在问题来了,第一个问题,什么是ThreadLocalMap,如果这个map不存在怎么办?第二个问题,setInitialValue()是个什么东西。接下来就来看看这两个问题的答案。

四、 ThreadLocalMap和setInitialValue

说白了,ThreadLocalMap就是一个map,是线程私有的,其中存放着各种ThreadLocal变量及其对应的键值。如果当前线程还不存在ThreadLocalMap,则会新建一个初始容量为16的数组,并把第一个键和值放入该map中。代码如下:

ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
            table = new Entry[INITIAL_CAPACITY];
            int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
            table[i] = new Entry(firstKey, firstValue);
            size = 1;
            setThreshold(INITIAL_CAPACITY);
        }

下面来看看setInitialValue()方法的源码:

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;
    }
protected T initialValue() {
        return null;
    }

setInitialValue()方法首先调用initialValue()方法,而initialValue()方法中,直接返回null,即将value初始化为null值。

五、 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);
        }
    }

该方法传入value值作为参数,如果map不为空,则对其进行赋值,如果为空,则调用creatMap方法,而creatMap方法最终调用的还是上文所贴出的代码。

六、remove()方法

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;
                }
            }
        }

根据当前ThreadLocal变量找到相应位置,如果键值相等,则删除,否则进行线性探测,直到找出需要删除的位置。

七、如何解决hash冲突

使用线性探测法,如果计算出的位置中已经有值了,则继续寻找下一个位置。增量为HASH_INCREMENT,是一个固定常数。

private static final int HASH_INCREMENT = 0x61c88647;
private final int threadLocalHashCode = nextHashCode();
private static int nextHashCode() {
        return nextHashCode.getAndAdd(HASH_INCREMENT);
    }
【顶刊TAC复现】事件触发模型参考自适应控制(ETC+MRAC):针对非线性参数不确定性线性部分时变连续系统研究(Matlab代码实现)内容概要:本文档介绍了“事件触发模型参考自适应控制(ETC+MRAC)”的研究与Matlab代码实现,聚焦于存在非线性参数不确定性且具有时变线性部分的连续系统。该研究复现了顶刊IEEE Transactions on Automatic Control(TAC)的相关成果,重点在于通过事件触发机制减少控制器更新频率,提升系统资源利用效率,同时结合模型参考自适应控制策略增强系统对参数不确定性和外部扰动的鲁棒性。文档还展示了大量相关科研方向的技术服务内容,涵盖智能优化算法、机器学习、路径规划、电力系统、信号处理等多个领域,并提供了Matlab仿真辅导服务及相关资源下载链接。; 适合人群:具备自动控制理论基础、非线性系统分析背景以及Matlab编程能力的研究生、博士生及科研人员,尤其适合从事控制理论与工程应用研究的专业人士。; 使用场景及目标:① 复现顶刊TAC关于ETC+MRAC的先进控制方法,用于非线性时变系统的稳定性与性能优化研究;② 学习事件触发机制在节约通信与计算资源方面的优势;③ 掌握模型参考自适应控制的设计思路及其在不确定系统中的应用;④ 借助提供的丰富案例与代码资源开展科研项目、论文撰写或算法验证。; 阅读建议:建议读者结合控制理论基础知识,重点理解事件触发条件的设计原理与自适应律的构建过程,运行并调试所提供的Matlab代码以加深对算法实现细节的理解,同时可参考文中列举的其他研究方向拓展应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值