ThreadLocal类【线程数据共享和安全】

ThreadLocal是Java中用于线程局部变量的类,它可以实现线程间的独立数据存储,解决多线程数据安全问题。文章详细介绍了ThreadLocal的set和get方法的源码解析,以及如何通过实例展示其工作原理。通过一个简单的案例,展示了如何在不同类中使用同一个ThreadLocal对象进行数据共享。
摘要由CSDN通过智能技术生成

目录

ThreadLocal类 简介

ThreadLocal 类的方法

常用方法

 set()和get()方法 源码解读

简单案例


ThreadLocal类 简介

1、ThreadLocal 可以实现在同一个线程数据共享, 从而解决多线程数据安全问题

2、ThreadLocal 可以使用set 方法给当前线程关联一个数据【普通变量、对象、数组】

3、ThreadLocal 可以像 Map 一样存取数据,其中key 为当前线程, value 为当前线程关联的那个数据

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

5、每个 ThreadLocal 对象实例定义的时候,一般为 static 类型

6、ThreadLocal 中保存数据,在线程销毁后,会自动释放


ThreadLocal 类的方法

常用方法

//创建ThreadLocal对象
public static ThreadLocal<Object> myThreadLocal = new ThreadLocal<>();

//给 myThreadLocal对象 关联一个数据
myThreadLocal.set(object);

//取出 myThreadLocal对象 关联的数据
myThreadLocal.get();

//删除 myThreadLocal对象 关联的数据
myThreadLocal.remove();

 set()和get()方法 源码解读

//set()解读
public void set(T value) {
    //1. 获取当前线程, 关联到当前线程
    Thread t = Thread.currentThread();
    //2. 通过线程对象, 获取到ThreadLocalMap
    //   ThreadLocalMap :
    //(ThreadLocal类 的静态内部类,也是在这里使ThreadLocalMap里只有一个Entry节点)
    ThreadLocalMap map = getMap(t);
    //3. 如果map不为null, 将数据(普通变量、对象、数组) 放入map
    //   重复set, 原先的数据就会被替换
    //4. 如果map为null, 就创建一个和当前线程关联的ThreadLocalMap, 并且该数据放入
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}



//get()解读
public T get() {
         //1. 先得到当前的线程对象
        Thread t = Thread.currentThread();
        //2.通过线程获取到对应的ThrealLocalMap
        ThreadLocalMap map = getMap(t);
        if (map != null) {
             //3. 如果map不为空, 根据当前的 threadlocal对象, 得到对应的Entry
            ThreadLocalMap.Entry e = map.getEntry(this);
            //4. 如果e 不为null, 返回当前threadlocal关联的数据value
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
}

简单案例

MyThreadlocal类的 Test内部类C1类、C2类 三个类 使用同一个同一个线程里的threadLocal对象 进行数据共享操作 

MyThreadlocal类


public class MyThreadlocal {
    public static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

    public static class Test implements Runnable{

        @Override
        public void run() {
            Integer integer = new Integer(999);
            threadLocal.set(integer);
            System.out.println("Test 放入了 integer= " + integer);

            System.out.println("Test 的run()方法中的线程为:" + Thread.currentThread().getName()
                    + " integer= " + integer);

            new C1().method_C1();
        }
    }

    public static void main(String[] args) {
        new Thread(new Test()).start();
    }
}

 C1类


public class C1 {
    public void method_C1(){
        Integer integer = MyThreadlocal.threadLocal.get();

        System.out.println("在C1的method_C1() 中的线程name= " +
                Thread.currentThread().getName() + " integer= " + integer);
        new C2().method_C2();
    }
}

C2类


public class C2 {
    public void method_C2(){
        Integer integer = MyThreadlocal.threadLocal.get();

        System.out.println("在C2的method_C2() 中的线程name= " +
                Thread.currentThread().getName() + " integer= " + integer);
    }
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值