Java随笔2-InheritableThreadLocal

阅读本文前,需要了解

① ThreadLocal的特性,参考:Java随笔1-ThreadLocal

② Inheritable:adj. 可继承的;会遗传的

1、特性

相比ThreadLocal,InheritableThreadLocal有什么特性?可从以下demo窥探一二:

import org.junit.Test;

import java.util.concurrent.CountDownLatch;

public class InheritableTLTest {


    InheritableThreadLocal<String> inheritableTL = new InheritableThreadLocal<>();

    ThreadLocal<String> threadLocal = new ThreadLocal<>();


    @Test
    public void compare() throws InterruptedException {
        threadLocal.set("祖先1");
        inheritableTL.set("祖先2");

        CountDownLatch latch = new CountDownLatch(2);
        new Thread(() -> {
            System.out.println("threadLocal, 儿子线程取出:" + threadLocal.get());
            System.out.println("inheritableTL, 儿子线程取出:" + inheritableTL.get() + "\n");

            threadLocal.set("儿子1");
            inheritableTL.set("儿子2");
            latch.countDown();
            new Thread(() -> {
                System.out.println("threadLocal, 孙子线程取出:" + threadLocal.get());
                System.out.println("inheritableTL, 孙子线程取出:" + inheritableTL.get() + "\n");

                threadLocal.set("孙子1");
                inheritableTL.set("孙子2");
                latch.countDown();
            }).start();
        }).start();

        latch.await();
        System.out.println("threadLocal, 主线程取出:" + threadLocal.get());
        System.out.println("inheritableTL, 主线程取出:" + inheritableTL.get());
    }
}

 demo执行结果如下:

threadLocal, 儿子线程取出:null
inheritableTL, 儿子线程取出:祖先2

threadLocal, 孙子线程取出:null
inheritableTL, 孙子线程取出:儿子2

threadLocal, 主线程取出:祖先1
inheritableTL, 主线程取出:祖先2

从结果看出,主线程设置了“祖先信息”,能通过InheritableThreadLocal传递给了儿子线程,无法通过ThreadLocal传递给儿子线程;儿子线程与孙子线程之间的传递同样如此。另外,儿子、孙子线程修改了变量,并不影响最后的主线程拿到最初设置的信息。

结论:相比ThreadLocal,InheritableThreadLocal可以在父子线程之间传递数据。

2、原理

Thread部分源码如下:

public class Thread implements Runnable {

    private Runnable target;

    ThreadLocal.ThreadLocalMap threadLocals = null;

    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }
    
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;
        //父线程
        Thread parent = currentThread();
        ...
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                    ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;
    }
}

可以看出,线程类有2个属性:threadLocals、inheritableThreadLocals,父线程使用new Thread(Runnable target)创建子线程的时候,会拷贝他的inheritableThreadLocals赋值给儿子线程的inheritableThreadLocals。

在调用ThreadLocal的get()方法时,ThreadLocal类的getMap()方法返回了线程的threadLocals属性,inheritableThreadLocals覆盖了getMap()方法返回了线程的inheritableThreadLocals属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThinkPHP 是一个优秀的PHP框架,可以帮助我们快速开发高质量的 Web 应用程序。因此,使用 ThinkPHP 来开发 OA 系统是非常方便和实用的。下面我们来讨论一下如何使用 ThinkPHP 来开发一个人力资源管理系统。 1. 创建数据库 首先,我们需要创建一个数据库来存储我们的数据。在该数据库中,我们需要创建一些表来存储员工信息、部门信息、职位信息、薪资信息等等。我们可以使用 MySQL 数据库来创建这些表。 2. 创建 ThinkPHP 项目 在创建完数据库之后,我们需要创建一个 ThinkPHP 项目来实现我们的 OA 系统。我们可以使用 ThinkPHP 官方提供的命令行工具来创建项目,具体命令如下: ``` composer create-project topthink/think oa ``` 执行完上述命令后,会在当前目录下创建一个名为 oa 的 ThinkPHP 项目。 3. 配置数据库 在项目创建好之后,我们需要配置数据库连接信息。在项目的 `.env` 文件中,我们可以配置数据库的相关信息,如下所示: ``` # 数据库类型 DB_CONNECTION=mysql # 数据库地址 DB_HOST=127.0.0.1 # 数据库端口 DB_PORT=3306 # 数据库名 DB_DATABASE=oa # 数据库用户名 DB_USERNAME=root # 数据库密码 DB_PASSWORD= ``` 我们需要根据自己的实际情况来修改这些配置项。 4. 创建控制器和模型 在 ThinkPHP 中,我们可以通过创建控制器和模型来实现 OA 系统的功能。我们可以使用命令行工具来快速创建控制器和模型,具体命令如下: ``` # 创建控制器 php think make:controller Index # 创建模型 php think make:model User ``` 执行完上述命令后,会在项目中生成一个名为 Index 的控制器和一个名为 User 的模型。 5. 实现功能 在创建好控制器和模型之后,我们就可以开始实现 OA 系统的功能了。比如,我们可以实现员工信息的添加、修改、删除、查询等操作,部门信息的添加、修改、删除、查询等操作,职位信息的添加、修改、删除、查询等操作,薪资信息的添加、修改、删除、查询等操作等等。我们可以在控制器中编写处理逻辑,在模型中编写数据库操作。最后,我们可以使用视图来展示数据。 6. 测试系统 在实现完功能之后,我们需要对系统进行测试。我们可以使用浏览器或者 Postman 等工具来测试系统的功能是否正常。如果有问题,我们可以根据错误提示来进行调试和修复。 总之,使用 ThinkPHP 来开发 OA 系统是非常方便和实用的。我们可以根据自己的实际情况来定制系统的功能和界面,从而更好地管理公司的人力资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值