InheritableThreadLocal
简介
主要是用来解决Threadlocal无法传递变量到子线程的不足。
应用
用户登录退出场景。
public class InheritableThreadLocalDemo {
private static final InheritableThreadLocal<String> curName = new InheritableThreadLocal<>();
public void login(String name) {
System.out.println(name + " login");
curName.set(name);
}
public void getCur() {
String s = curName.get();
System.out.println(s + " get");
new Thread(
()->{
System.out.println("子线程获取name:"+curName.get());
}
).start();
}
public void logout() {
System.out.println(curName.get() + " logout");
curName.remove();
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
InheritableThreadLocalDemo threadLocalDemo = new InheritableThreadLocalDemo();
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(() -> {
threadLocalDemo.login(1 + "");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadLocalDemo.getCur();
threadLocalDemo.logout();
});
executorService.execute( () -> {
threadLocalDemo.login(2 + "");
threadLocalDemo.getCur();
threadLocalDemo.logout();
});
System.out.println("---------");
}
}可以看到,子线程成功获取到父线程的变量。
1 login
---------
2 login
2 get
2 logout
子线程获取name:2
1 get
1 logout
子线程获取name:1核心原理
InheritableThreadLocal使用的是Thread的 inheritableThreadLocals属性。
在Thread初始化的时候:
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
...
//当父线程的inheritableThreadLocals不为null,就会把其复制给当前线程。
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
...
需要注意的是,只有在子线程创建的时候,才会复制父线程的inheritableThreadLocals。后续2者之间再发生变量变化,是互相不会影响的。
如果想要随时更新变量,可以查看TransmittableThreadLocal
Last updated
Was this helpful?