InheritableThreadLocal使用详解

System.out.println(“value:”+threadLocal.get());

Thread thread = new Thread(new Runnable() {

@Override

public void run() {

String value = threadLocal.get();

System.out.println(“value:”+value);

}

});

thread.start();

}

}

上面代码中在主线程中设置了一个ThreadLocal变量,并将其值设置为mainThread。然后有在主线程中开启了一个子线程thread,并试图获取在主线程中set的ThreadLocal变量的值。但是结果如下:

value:mainThread

value:null

通过前面的文章介绍,对于上面的结果我们也就非常容易理解了。每个线程都会有一个自己的ThreadLocalMap,所以子线程在调用get方法拿值的时候其实访问的是自己的ThreadLocalMap,这个Map和主线程的Map是两个不同的对象,所以肯定是拿不到值的。

那么Java中有没有类似的对象能实现上面的功能呢?有,InheritableThreadLocal就能实现这样的功能,这个类能让子线程继承父线程中已经设置的ThreadLocal值。

InheritableThreadLocal简单使用#


还是以上面的列子为列,我们只需要将ThreadLocal变成InheritableThreadLocal就行了。

public class InheritableThreadLocalDemo {

private static InheritableThreadLocal threadLocal = new InheritableThreadLocal<>();

public static void main(String[] args) {

threadLocal.set(“mainThread”);

System.out.println(“value:”+threadLocal.get());

Thread thread = new Thread(new Runnable() {

@Override

public void run() {

String value = threadLocal.get();

System.out.println(“value:”+value);

}

});

thread.start();

}

}

执行结果如下:

value:mainThread

value:mainThread

InheritableThreadLocal原理分析#


先看下InheritableThreadLocal的源代码:

public class InheritableThreadLocal extends ThreadLocal {

protected T childValue(T parentValue) {

return parentValue;

}

ThreadLocalMap getMap(Thread t) {

return t.inheritableThreadLocals;

}

void createMap(Thread t, T firstValue) {

t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);

}

}

这个类继承了ThreadLocal,并且重写了getMap和createMap方法,区别就是将 ThreadLocal 中的 threadLocals 换成了 inheritableThreadLocals,这两个变量都是ThreadLocalMap类型,并且都是Thread类的属性。

下面就一步步来看下InheritableThreadLocal为什么能拿到父线程中的ThreadLocal值。

step1:InheritableThreadLocal获取值先调用了get方法,所以我们直接看看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方法和ThreadLocal中是一样的,唯一有区别的就是其中的getMap方法重写了,返回的是inheritableThreadLocals属性。这个属性也是一个ThreadLocalMap类型的变量。那么从这边就可以推断出来:肯定是在某处将父线程中的ThreadLocal值赋值到了子线程的inheritableThreadLocals中。

step2:在源代码中搜索哪些地方使用到了inheritableThreadLocals这个属性,最后找到这段代码:

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!**

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值