一、复习
二、threadLocal不具有继承性
package com. ruigege. threadFoundation1;
public class ThreadLocalExtend {
public static ThreadLocal< String> threadLocal = new ThreadLocal < > ( ) ;
public static void main ( String[ ] args) {
Thread thread = new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
threadLocal. set ( "我是子线程的" ) ;
System. out. println ( threadLocal. get ( ) ) ;
}
} ) ;
thread. start ( ) ;
try {
Thread. sleep ( 1000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
System. out. println ( threadLocal. get ( ) ) ;
}
}
从上面的两个ThreadLocal实例中可以看出,实例不具有继承性,也就是说主线程和子线程threadLocal变量值是不相等的,这也符合前面源码解析set方法。
二、如何让子线程能够访问到父线程的值呢?
我们还有一个成员变量没讲呢,那就是inheritableThreadLocal 我们先说一个类InheritableThreadLocal,这个类继承字ThreadLocal
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) ;
}
}
后两个方法,可以看出来,其实就是把threadLocals成员变量换成了inheritaleThreadLocals。这样就完成替换了,下面看一下如何完成子线程调用父线程的变量 先来看看Thread源码
public Thread ( Runnable target) {
init ( null, target, "Thread-" + nextThreadNum ( ) , 0 ) ;
}
private void init ( ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) {
. . . .
Thread parent = currentThread ( ) ;
. . . .
if ( parent. inheritableThreadLocal != null) {
this . inheritableThreadLocals = ThreadLocal. createInheritedMap ( parent. inheritableThreadLocals;
this . stackSize = stackSize) ;
tid = nextThreadID ( ) ;
}
static ThreadLocalMap createInheritedMap ( Thread ThreadLocalMap map) {
return new ThreadLocalMap ( map) ;
}
如上代码在创建线程的时候,在构造函数里面会调用init方法 进入到init方法里面,语句4就是获取了父线程,然后在后面的判断里,先判断一下父线程的inheritableThreadLocals是不是为空,如果不为空,那么我们赋值给子线程里面的inheritableThreadLocals,其中调用了一个函数,其实这个函数就是重新建立了一个ThreadLocalMap实例,接下来我们来观察一下源码
package com. ruigege. threadFoundation1;
public class ThreadLocalMap {
private Entry[ ] table;
private T
private ThreadLocalMap ( ThreadLocalMap parentMap) {
Entry[ ] parentTable = parentMap. table;
int len = parentTable. length;
setThreshole ( 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. chirld ( 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++ ;
}
}
}
}
}
这段代码的基本思想就是复制父线程的inheritableThreadLocals变量到子线程中去。
三、并发和并行
并发指的是一段时间内多个线程同时执行,并且没有停止; 并行指的是单位时间内多个线程同时执行,并且没有停止; 并发强调的是一段时间,可能是由多个单位时间内组成的,并且可能一个单位时间只运行了一个线程。
四、源码: