ThreadLocal是什么?简单易懂

在并发编程中时常有这样一种需求:每条线程都需要存取一个同名变量,但每条线程中该变量的值均不相同。把对象或资源封闭在当前所在线程里,这样便成为了该线程的内部变量。

基本上,ThreadLocal对外提供的方法只有三个:

set(obj):向当前线程中存储数据
get():获取当前线程中的数据
remove():删除当前线程中的数据

最初碰到是在一个FTP服务器的小项目里,需要将share中的user用户信息存入每个用户新开的线程中,所以肯定要把线程和用户信息严格对应起来,如下图
在这里插入图片描述
在这里插入图片描述

下面举一个例子,看看怎么使用ThreadLocal:

public class ThreadLocalDemo {
    
    public static void main(String[] args) throws InterruptedException {

        final ThreadLocal<String> threadLocal = new ThreadLocal<>();
        threadLocal.set("main-thread : Hello");
        
        Thread thread = new Thread(() -> {
            // 获取不到主线程设置的值,所以为null
            System.out.println(threadLocal.get());
            threadLocal.set("sub-thread : World");
            System.out.println(threadLocal.get());
        });
        // 启动子线程
        thread.start();
        // 让子线程先执行完成,再继续执行主线
        thread.join();
        // 获取到的是主线程设置的值,而不是子线程设置的
        System.out.println(threadLocal.get());
        threadLocal.remove();
        System.out.println(threadLocal.get());
    }
}

运行结果:

null
sub-thread : World
main-thread : Hello
null

我们看一下ThreadLocal的set方法源码,通过获取当前线程,ThreadLocalMap是ThreadLocal的一个静态内部类

public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}

ThreadLocalMap中还有一个内部类Entry ,这是Entry源码:

static class Entry extends WeakReference<ThreadLocal<?>> {
    Object value;
    
    Entry(ThreadLocal<?> k, Object v) {
        super(k);
        value = v;
    }
}

再看看Thread中成员变量threadLocals的源码:

ThreadLocal.ThreadLocalMap threadLocals = null;

可见ThreadLocal并不维护ThreadLocalMap,它并不是一个存储数据的容器,它只是相当于一个工具包,提供了操作该容器的方法,如get、set、remove等。

而ThreadLocal内部类ThreadLocalMap才是存储数据的容器,并且该容器由Thread维护。每一个Thread对象均含有一个ThreadLocalMap类型的成员变量threadLocals,它存储本线程中所有ThreadLocal对象及其对应的值。

ThreadLocalMap由一个个Entry对象构成,一个Entry由ThreadLocal对象和Object构成。

恍然大悟!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值