初识InheritableThreadLocal
一直来只知道ThreadLocal,直到最近看slf4j MDC实现代码的时候,才认识了InheritableThreadLocal.InheritableThreadLocal顾名思义,可继承的ThreadLocal.
看类描述:
This class extends
<
tt
>ThreadLocal
</
tt
> to provide inheritance of values
* from parent thread to child thread: when a child thread is created, the
* child receives initial values for all inheritable thread-local variables
* for which the parent has values.
* from parent thread to child thread: when a child thread is created, the
* child receives initial values for all inheritable thread-local variables
* for which the parent has values.
测试代码:
1
public
class Test {
2
3 public static void main(String[] args) {
4 // 使用ThreadLocal,父子线程之间,不共享Value
5 final ThreadLocal<String> tl = new ThreadLocal<String>();
6 tl.set("ThreadLocal-VAL");
7 System.out.println("Main-1:" + tl.get());
8 new Thread() {
9 public void run() {
10 System.out.println("Child-1:" + tl.get());
11 };
12 }.start();
13
14 // 使用InheritableThreadLocal,父线程Value可让子线程共享
15 final ThreadLocal<String> itl = new InheritableThreadLocal<String>();
16 itl.set("InheritableThreadLocal-VAL");
17 System.out.println("Main-2:" + itl.get());
18 new Thread() {
19 public void run() {
20 System.out.println("Child-2:" + itl.get());
21 };
22 }.start();
23
24 }
25 }
2
3 public static void main(String[] args) {
4 // 使用ThreadLocal,父子线程之间,不共享Value
5 final ThreadLocal<String> tl = new ThreadLocal<String>();
6 tl.set("ThreadLocal-VAL");
7 System.out.println("Main-1:" + tl.get());
8 new Thread() {
9 public void run() {
10 System.out.println("Child-1:" + tl.get());
11 };
12 }.start();
13
14 // 使用InheritableThreadLocal,父线程Value可让子线程共享
15 final ThreadLocal<String> itl = new InheritableThreadLocal<String>();
16 itl.set("InheritableThreadLocal-VAL");
17 System.out.println("Main-2:" + itl.get());
18 new Thread() {
19 public void run() {
20 System.out.println("Child-2:" + itl.get());
21 };
22 }.start();
23
24 }
25 }
输出内容:
Main-1:ThreadLocal-VAL
Main-2:InheritableThreadLocal-VAL
Child-1:null
Child-2:InheritableThreadLocal-VAL
......分隔符号......
顺带着简单说下MDC.(Mapped Diagnostic Context). 中文直译太恶心了,我理解的意思是,和环境相关的上下文信息.
比如在web应用中,我们可以把用户的ip,访问url等放入到这个上下文中,log打印的时候,就能得到这个信息.
在slf4j BasicMDCAdapter实现中,就是用了InheritableThreadLocal
1
public
class BasicMDCAdapter
implements MDCAdapter {
2
3 private InheritableThreadLocal inheritableThreadLocal = new InheritableThreadLocal();
4
5 //
.
6
7 }
2
3 private InheritableThreadLocal inheritableThreadLocal = new InheritableThreadLocal();
4
5 //
![](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
6
7 }
ThreadLocal有个缺陷,在子线程里无法访问父线程的变量,
InheritableThreadLocal 解决了这个问题,自动会把父线程的变量传递个子线程,
子线程只能用,修改了不会影响父线程的东西
这里仍然需要注意并发实现~
InheritableThreadLocal 解决了这个问题,自动会把父线程的变量传递个子线程,
子线程只能用,修改了不会影响父线程的东西
这里仍然需要注意并发实现~
- public class Test {
- private final static InheritableThreadLocal<String> holder = new InheritableThreadLocal<String>();
- public static void main(String[] args){
- holder.set("aaa");
- System.out.println("begin=" + holder.get());
- Thread a = new Thread(){
- public void run() {
- System.out.println("thread-begin=" + holder.get());
- holder.set("vvvvvvvvvvvvv");
- System.out.println("thread-end=" + holder.get());
- }
- };
- a.start();
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("end=" + holder.get());