线程数据共享和安全 -ThreadLocal

大家好呀,我是小笙!这部分是我学习ThreadLocal的笔记

线程数据共享和安全 - ThreadLocal

概述

ThreadLocal是一个将在多线程中为每一个线程创建单独的变量副本的类; 当使用ThreadLocal来维护变量时, ThreadLocal会为每个线程创建单独的变量副本, 避免因多线程操作共享变量而导致的数据不一致的情况

每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数 据,就需要使用多个 ThreadLocal 对象实例

image-20220512211018686

代码示例

image-20220512234534965

public class Dog {}

// ThreadLocalDemo
public class ThreadLocalDemo implements Runnable{
    public static ThreadLocal<Object> threadLocal= new ThreadLocal<>();
    public static void main(String[] args) {
        // 创建进程
        new Thread(new ThreadLocalDemo()).start();
    }

    @Override
    public void run() {
        Dog dog = new Dog();
        threadLocal.set(dog);
        System.out.println("ThreadLocalDemo: " + Thread.currentThread().getName());
        new Service().update();
    }
}

// Service
public class Service {
    public void update() {
        Object o = ThreadLocalDemo.threadLocal.get();
        System.out.println(o.getClass()); // threadLocal.Dog
        String name = Thread.currentThread().getName();
        System.out.println("在 Service 的 update() 线程 name= " + name);
        new Dao().update();
    }
}

// Dao
public class Dao {
    public void update() {
        Object o = ThreadLocalDemo.threadLocal.get();
        System.out.println(o.getClass()); // threadLocal.Dog
        String name = Thread.currentThread().getName();
        System.out.println("在 Dao 的 update() 线程是= " + name);
    }
}

源码分析

// ThreadLocal.get()方法
public T get() {
    // 获取当前进程t 
    Thread t = Thread.currentThread();
    // 从容器map中获取该线程的threadLocals
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}

// ThreadLocal.set(数据)方法
public void set(T value) {
    // 获取当前进程t 
    Thread t = Thread.currentThread();
    // 从容器map中获取该线程的threadLocals
    ThreadLocalMap map = getMap(t);
    /*
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }
    */
    if (map != null) {
        // 如果存在,则覆盖该 threadLocals对象对应的原来数据(可以是对象)
        map.set(this, value);
    } else {
        // 如果不存在,则创建t.threadLocals,存入ThreadLocalMap对象
        // key:this(调用该方法的threadLocal对象)value:需要存入的数据
        createMap(t, value);
        /*
        void createMap(Thread t, T firstValue) {
            t.threadLocals = new ThreadLocalMap(this, firstValue);
        }
        */
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗念笙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值