带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(13)https://developer.aliyun.com/article/1340056?groupCode=taobaotech
思考&小结
ThreadLocalMap中的Entry为什么要设计为弱引用类型?
若使用强引用类型,则threadlocal的引用链为:Thread -> ThreadLocal.ThreadLocalMap -> Entry[] -> Entry -> key(threadLocal对象)和value;在这种场景下,只要这个线程还在运行(如线程池场景),若不调用remove方法,则该对象及关联的所有强引用对象都不会被垃圾回收器回收。
使用static和不使用static修饰threadlocal变量有和区别?
若使用static关键字进行修饰,则一个线程仅对应一个线程变量;否则,threadlocal语义变为perThread-per- Instance,容易引发内存泄漏,如下述示例:
public class ThreadLocalTest { public static class ThreadLocalDemo { private ThreadLocal<String> threadLocalHolder = new ThreadLocal(); public void setValue(String value) { threadLocalHolder.set(value);
7 |
|
} |
8 |
|
|
9 |
|
public String getValue() { |
10 |
|
return threadLocalHolder.get(); |
11 |
|
} |
12 |
|
} |
13 |
|
|
14 |
|
public static void main(String[] args) { |
15 |
|
int count = 3; |
16 |
|
List<ThreadLocalDemo> list = new LinkedList<>(); |
17 |
|
for (int i = 0; i < count; i++) { |
18 |
|
ThreadLocalDemo demo = new ThreadLocalDemo(); |
19 |
|
demo.setValue("demo-" + i); |
20 |
|
list.add(demo); |
21 |
|
} |
22 |
|
System.out.println(); |
23 |
|
} |
24 |
} |
|
在上述main方法第22行debug,可见线程的threadLocals变量中有3个threadlocal实例。在工程实践中,使用 threadlocal时通常期望一个线程只有一个threadlocal实例,因此,若不使用static修饰,期望的语义发生了变化, 同时易引起内存泄漏。
带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(15)https://developer.aliyun.com/article/1340054?groupCode=taobaotech