代码
/** * @author Lux Sun * @date 2021/12/30 */ public class Cat { public Cat(String name) { this.name = name; } private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Cat{" + "name='" + name + '\'' + '}'; } }
/** * 容器上下文 * @author Lux Sun * @date 2021/12/29 */ public class ContainerContext { public ContainerContext(String id, Cat cat) { this.id = id; this.cat = cat; } private String id; private Cat cat; public String getId() { return id; } public void setId(String id) { this.id = id; } public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } @Override public String toString() { return "ContainerContext{" + "id='" + id + '\'' + ", cat=" + cat + '}'; } }
/** * 容器处理器 * @author Lux Sun * @date 2021/12/29 */ public class ContainerContextHandler { /** * 父子线程圈传递 ContainerContext */ private static final InheritableThreadLocal<ContainerContext> INHERITABLE_THREAD_LOCAL = new InheritableThreadLocal<>(); /*************************** Getter/Setter ***************************/ public static ContainerContext getContainerContext() { return INHERITABLE_THREAD_LOCAL.get(); } public static void setContainerContext(ContainerContext containerContext) { INHERITABLE_THREAD_LOCAL.set(containerContext); } }
import lombok.SneakyThrows; import java.util.concurrent.TimeUnit; /** * @author Lux Sun * @date 2021/12/30 */ public class Test { /** * 主线程 * @param args */ public static void main(String[] args) throws InterruptedException { // 主线程 ContainerContext containerContext = new ContainerContext("main", new Cat("main_cat")); ContainerContextHandler.setContainerContext(containerContext); // 子线程 new ChildThread().start(); TimeUnit.MILLISECONDS.sleep(500); // 打印主线程信息 print(); } /** * 子线程 */ private static class ChildThread extends Thread { @SneakyThrows @Override public void run() { // 打印主线程信息 print(); ContainerContext containerContext = new ContainerContext("child", new Cat("child_cat")); ContainerContextHandler.setContainerContext(containerContext); // 打印子线程信息 print(); // 孙子线程 new GrandChildThread().start(); TimeUnit.MILLISECONDS.sleep(200); // 打印子线程信息 print(); } } /** * 孙子线程 */ private static class GrandChildThread extends Thread { @Override public void run() { // 打印子线程信息 print(); ContainerContext containerContext = new ContainerContext("grandchild", new Cat("grandchild_cat")); ContainerContextHandler.setContainerContext(containerContext); // 打印孙子线程信息 print(); } } /** * 打印 * @param */ private static void print() { System.out.println(ContainerContextHandler.getContainerContext()); } }
输出结果
ContainerContext{id='main', cat=Cat{name='main_cat'}} ContainerContext{id='child', cat=Cat{name='child_cat'}} ContainerContext{id='child', cat=Cat{name='child_cat'}} ContainerContext{id='grandchild', cat=Cat{name='grandchild_cat'}} ContainerContext{id='child', cat=Cat{name='child_cat'}} ContainerContext{id='main', cat=Cat{name='main_cat'}}
总结
一句话:父子线程组隔离通信机制。
使用场景:父 - 子 - 孙子线程通信传递,但如果想要到某一个子树更新内容,不会影响父或祖父线程,但是会从自己这边开始下去继承的时候会保持一致。所以这就解决了父子线程组的通信,组与组之间的隔离机制。
这里还涉及 InheritableThreadLocal 对象对于可变对象 & 不可变对象的不同结果,详情看这篇文章:……