JavaSE-多线程(14)- ThreadLocal 使用及源码解析

本文解析了Java中ThreadLocal的使用方法,重点讲解了set、get和ThreadLocalMap的内部实现,以及ThreadLocal如何实现线程间的数据隔离与同步区别。实例演示了如何利用ThreadLocal避免线程间数据共享的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaSE-多线程(14)- ThreadLocal 使用及源码解析

ThreadLocal 称为线程变量,在 ThreadLocal 中定义的变量被当前线程独有,看下例:
类 ThreadLocalTest 中 有一个ThreadLocal 属性,它用来保存 User 对象,线程 t1 和线程 t2 各自调用 ThreadLocalTest setUser 方法给 ThreadLocal 赋值,然后调用 run 方法取出 ThreadLocal 中的User对象,从输出结果中可以看出,t1 t2 中的属性相互不影响。

public class ThreadLocalTest {

    private static ThreadLocal<User> tl = new ThreadLocal<>();

    public  void setUser(User user) {
        tl.set(user);
    }

    public  User getUser() {
        return tl.get();
    }

    void run(){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " " + this.getUser().getName());
    }

    public static void main(String[] args) {
        ThreadLocalTest threadLocalTest = new  ThreadLocalTest();
        Thread t1 = new Thread(() -> {
            threadLocalTest.setUser(new User("张三"));
            threadLocalTest.run();
        });
        t1.setName("t1");
        t1.start();

        Thread t2 = new Thread(() -> {
            threadLocalTest.setUser(new User("李四"));
            threadLocalTest.run();
        });
        t2.setName("t2");
        t2.start();
    }
}

class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
t1 张三
t2 李四`

ThreadLocal 方法解析

set 方法
从 set 方法中我们只能看出,ThreadLocal set 方法将变量的值存放到 ThreadLocalMap 键值对中,如果 ThreadLocalMap 为空则通过 createMap 方法创建

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

getMap 方法

getMap 方法形参为 Thread ,一眼可以看出 threadLocals 为 Thread 的属性

ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}

Thread 类

public  class Thread implements Runnable {
	ThreadLocal.ThreadLocalMap threadLocals = null;
}

createMap 方法
创建 ThreadLocalMap 并将值赋值给 Thread threadLocals 属性

void createMap(Thread t, T firstValue) {
    t.threadLocals = new ThreadLocalMap(this, firstValue);
}

从以上分析不难看出,线程变量的本质就是每个线程都维护了一份自己线程变量的 Map

ThreadLocal 与 Synchronized 的区别

  1. Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。
  2. Synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。

参考:https://blog.csdn.net/u010445301/article/details/111322569

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值