这篇文章主要为大家详细介绍了java多线程编程之InheritableThreadLocal,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
InheritableThreadLocal的作用: 当我们需要在子线程中使用父线程中的值得时候我们就可以像使用ThreadLocal那样来使用InheritableThreadLocal了。
首先我们来看一下InheritableThreadLocal的jdk源码:
package java.lang; import java.lang.ref.*; public class InheritableThreadLocal<T> extends ThreadLocal<T> { 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); } }
这段代码就是InheritableThreadLocal的完整源码(删除了很长的注释)。
首先我们可以看到它是继承ThreadLocal类的,然后提供了:
protected T childValue(T parentValue){}方法,这就是InheritableThreadLocal的关键所在,它提供了这个方法,返回父线程中的值,如果还需要在父线程上添加值则可以重写childValue方法。
package InheritableThreadLocal; import java.util.Date; public class InheritableThreadLocaExt extends InheritableThreadLocal{ protected Object initialValue() { return new Date().getTime(); } protected Object childValue(Object parentValue) { return parentValue+"对继承值进行修改"; } } package InheritableThreadLocal; public class tool { public static InheritableThreadLocaExt t=new InheritableThreadLocaExt(); } package InheritableThreadLocal; public class MyThread extends Thread{ public void run() { try { for(int i=0;i<10;i++) { System.out.println("在线程A中:"+tool.t.get()); sleep(100); } } catch (InterruptedException e) { e.printStackTrace(); } } } package InheritableThreadLocal; public class test { public static void main(String[] args) { try { for(int i=0;i<10;i++) { System.out.println("主线程中值:"+tool.t.get()); Thread.sleep(100); } Thread.sleep(5000); MyThread thread=new MyThread(); thread.start(); }catch(InterruptedException e){ e.printStackTrace(); } } }
运行输出:
主线程中值:1508210392057
主线程中值:1508210392057
主线程中值:1508210392057
主线程中值:1508210392057
主线程中值:1508210392057
主线程中值:1508210392057
主线程中值:1508210392057
主线程中值:1508210392057
主线程中值:1508210392057
主线程中值:1508210392057
在线程A中:1508210392057对继承值进行修改
在线程A中:1508210392057对继承值进行修改
在线程A中:1508210392057对继承值进行修改
在线程A中:1508210392057对继承值进行修改
在线程A中:1508210392057对继承值进行修改
在线程A中:1508210392057对继承值进行修改
在线程A中:1508210392057对继承值进行修改
在线程A中:1508210392057对继承值进行修改
在线程A中:1508210392057对继承值进行修改
在线程A中:1508210392057对继承值进行修改
是不是有一个疑问,为什么子线程能获取父线程的数据?
我们可以看到InheritableThreadLocal重写了getMap方法和createMap方法,上一节讲ThreadLocal的时候我们知道,ThreadLocal的值是存储在一个叫ThreadLocals的变量中,但是现在返回一个InheritableThreadLocals,这个变量和ThreadLocals是一模一样的只是名字换了,那么究竟 为什么在新的 线程中 通过 threadlocal.get() 方法还能得到值呢?
我们看childValue方法可以猜测到可能在线程创建的时候,做了一些手脚,做了一些值得传递。
我们打开Thread类的源码的时候可以发现 :
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
所以当我们创建一个子线程的时候,他就存在一个和ThreadLocals的一样的InheritableThreadLocal变量,再往下看:
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, . . if (inheritThreadLocals && parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
重点是以下这段代码:
if (inheritThreadLocals && parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
继续看:
static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) { return new ThreadLocalMap(parentMap); }
private ThreadLocalMap(ThreadLocalMap parentMap) { Entry[] parentTable = parentMap.table; int len = parentTable.length; setThreshold(len); table = new Entry[len]; for (int j = 0; j < len; j++) { Entry e = parentTable[j]; if (e != null) { @SuppressWarnings("unchecked") ThreadLocal<Object> key = (ThreadLocal<Object>) e.get(); if (key != null) { Object value = key.childValue(e.value); Entry c = new Entry(key, value); int h = key.threadLocalHashCode & (len - 1); while (table[h] != null) h = nextIndex(h, len); table[h] = c; size++; } } } }
有这段代码,先得到父线程(也就是当前执行的线程)的值,然后用for循环一个个的将父线程中的值放入我们新创建的值中。
以上是Java多线程中有关InheritableThreadLocal的详解的详细内容。更多信息请关注PHP中文网其他相关文章!

新兴技术对Java的平台独立性既有威胁也有增强。1)云计算和容器化技术如Docker增强了Java的平台独立性,但需要优化以适应不同云环境。2)WebAssembly通过GraalVM编译Java代码,扩展了其平台独立性,但需与其他语言竞争性能。

不同JVM实现都能提供平台独立性,但表现略有不同。1.OracleHotSpot和OpenJDKJVM在平台独立性上表现相似,但OpenJDK可能需额外配置。2.IBMJ9JVM在特定操作系统上表现优化。3.GraalVM支持多语言,需额外配置。4.AzulZingJVM需特定平台调整。

平台独立性通过在多种操作系统上运行同一套代码,降低开发成本和缩短开发时间。具体表现为:1.减少开发时间,只需维护一套代码;2.降低维护成本,统一测试流程;3.快速迭代和团队协作,简化部署过程。

Java'splatformindependencefacilitatescodereusebyallowingbytecodetorunonanyplatformwithaJVM.1)Developerscanwritecodeonceforconsistentbehavioracrossplatforms.2)Maintenanceisreducedascodedoesn'tneedrewriting.3)Librariesandframeworkscanbesharedacrossproj

要解决Java应用程序中的平台特定问题,可以采取以下步骤:1.使用Java的System类查看系统属性以了解运行环境。2.利用File类或java.nio.file包处理文件路径。3.根据操作系统条件加载本地库。4.使用VisualVM或JProfiler优化跨平台性能。5.通过Docker容器化确保测试环境与生产环境一致。6.利用GitHubActions在多个平台上进行自动化测试。这些方法有助于有效地解决Java应用程序中的平台特定问题。

类加载器通过统一的类文件格式、动态加载、双亲委派模型和平台无关的字节码,确保Java程序在不同平台上的一致性和兼容性,实现平台独立性。

Java编译器生成的代码是平台无关的,但最终执行的代码是平台特定的。1.Java源代码编译成平台无关的字节码。2.JVM将字节码转换为特定平台的机器码,确保跨平台运行但性能可能不同。

多线程在现代编程中重要,因为它能提高程序的响应性和资源利用率,并处理复杂的并发任务。JVM通过线程映射、调度机制和同步锁机制,在不同操作系统上确保多线程的一致性和高效性。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)