java多线程编程之InheritableThreadLocal
InheritableThreadLocal的作用:当我们需要在子线程中使用父线程中的值得时候我们就可以像使用ThreadLocal那样来使用InheritableThreadLocal了。
首先我们来看一下InheritableThreadLocal的jdk源码:
packagejava.lang; importjava.lang.ref.*; publicclassInheritableThreadLocalextendsThreadLocal { protectedTchildValue(TparentValue){ returnparentValue; } ThreadLocalMapgetMap(Threadt){ returnt.inheritableThreadLocals; } voidcreateMap(Threadt,TfirstValue){ t.inheritableThreadLocals=newThreadLocalMap(this,firstValue); } }
这段代码就是InheritableThreadLocal的完整源码(删除了很长的注释)。
首先我们可以看到它是继承ThreadLocal类的,然后提供了:
protectedTchildValue(TparentValue){}方法,这就是InheritableThreadLocal的关键所在,它提供了这个方法,返回父线程中的值,如果还需要在父线程上添加值则可以重写childValue方法。
packageInheritableThreadLocal;
importjava.util.Date;
publicclassInheritableThreadLocaExtextendsInheritableThreadLocal{
protectedObjectinitialValue(){
returnnewDate().getTime();
}
protectedObjectchildValue(ObjectparentValue){
returnparentValue+"对继承值进行修改";
}
}
packageInheritableThreadLocal;
publicclasstool{
publicstaticInheritableThreadLocaExtt=newInheritableThreadLocaExt();
}
packageInheritableThreadLocal;
publicclassMyThreadextendsThread{
publicvoidrun(){
try{
for(inti=0;i<10;i++){
System.out.println("在线程A中:"+tool.t.get());
sleep(100);
}
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
packageInheritableThreadLocal;
publicclasstest{
publicstaticvoidmain(String[]args){
try{
for(inti=0;i<10;i++){
System.out.println("主线程中值:"+tool.t.get());
Thread.sleep(100);
}
Thread.sleep(5000);
MyThreadthread=newMyThread();
thread.start();
}catch(InterruptedExceptione){
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.ThreadLocalMapinheritableThreadLocals=null;
所以当我们创建一个子线程的时候,他就存在一个和ThreadLocals的一样的InheritableThreadLocal变量,再往下看:
privatevoidinit(ThreadGroupg,Runnabletarget,Stringname, longstackSize,AccessControlContextacc, . . if(inheritThreadLocals&&parent.inheritableThreadLocals!=null) this.inheritableThreadLocals= ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
重点是以下这段代码:
if(inheritThreadLocals&&parent.inheritableThreadLocals!=null) this.inheritableThreadLocals= ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
继续看:
staticThreadLocalMapcreateInheritedMap(ThreadLocalMapparentMap){
returnnewThreadLocalMap(parentMap);
}
privateThreadLocalMap(ThreadLocalMapparentMap){
Entry[]parentTable=parentMap.table;
intlen=parentTable.length;
setThreshold(len);
table=newEntry[len];
for(intj=0;jkey=(ThreadLocal
有这段代码,先得到父线程(也就是当前执行的线程)的值,然后用for循环一个个的将父线程中的值放入我们新创建的值中。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。