多线程 - 一篇带你理解 InheritableThreadLocal 作用

举报
放羊的牧码 发表于 2022/05/20 18:08:41 2022/05/20
【摘要】 ​代码/** * @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; ...

代码

/**
 * @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'}}

总结

  1. 一句话:父子线程组隔离通信机制。
  2. 使用场景:父 - 子 - 孙子线程通信传递,但如果想要到某一个子树更新内容,不会影响父或祖父线程,但是会从自己这边开始下去继承的时候会保持一致。所以这就解决了父子线程组的通信,组与组之间的隔离机制。
  3. 这里还涉及 InheritableThreadLocal 对象对于可变对象 & 不可变对象的不同结果,详情看这篇文章:……
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。