ThreadLocal 实现原理

首先,在每个线程 Thread 内部有一个 Threadlocal.ThreadLocalMap 类型的成员变量 ThreadLocals,ThreadLocalMap 是 ThreadLocal 的内部类,这个 ThreadLocals 就是用来存储实际的变量副本,键值为当前的 ThreadLocal 对象,value 为变量副本。

初始时,在 Thread 里,threadlocals 为空,当通过 ThreadLocal 变量调用 get() 方法或 set() 方法,就会对 Thread 类中的 threadlocals 进行初始化,并且以当前 ThreadLocal 变量为键值,以 ThreadLocal 要保存的副本变量为 value,存到 threadlocals

然后再当前线程里面,如果要使用副本变量,就可以通过 get 方法在 threadlocals 里面查找。

本质上来说,ThreadLocal 只是用一个 Map 存储了不同 Thread 和 副本变量的对应关系,一个 Thread 对应一个变量。具体用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class nomalThread {
static java.lang.ThreadLocal<local> t;
//使用匿名函数重写 ThreadLocal 的 initialValue 方法
static {
t = new java.lang.ThreadLocal<local>() {
@Override
protected local initialValue() {
return new local();
}
};
}

public static void main(String[] args) {
//传入副本变量

A A1 = new A(t);
Thread thread1 = new Thread(A1);
Thread thread2 = new Thread(A1);
thread1.start();
thread2.start();

}

}


class A implements Runnable{
static java.lang.ThreadLocal<local> t;

public A(java.lang.ThreadLocal<local> t) {
this.t = t;
}


@Override
public void run() {

//调用 ThreadLocal的set()、get()方法时,会调用initialValue方法
//为 threadlocals 赋初值

while (t.get().getA()<50) {
t.get().add(2);
System.out.println(t.get().getA());
}
}
}

class local{
int a = 1;

public int getA() {
return a;
}

public void setA(int a) {
this.a = a;
}

public int add(int i){
return a=a+i;
}
}
-----------本文结束感谢您的阅读-----------
0%