线程数据共享和安全 -ThreadLocal

  |   0 评论   |   0 浏览

线程数据共享和安全 -ThreadLocal

1.什么是 ThreadLocal

  1. ThreadLocal 的作用,可以实现在同一个线程数据共享, 从而解决多线程数据安全问题.
  2. ThreadLocal 可以给当前线程关联一个数据(普通变量、 对象、 数组)set 方法 [源码!]
  3. ThreadLocal 可以像 Map 一样存取数据, key 为当前线程, get 方法
  4. 每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数 据, 就需要使用多个 ThreadLocal对象实例
  5. 每个 ThreadLocal 对象实例定义的时候, 一般为 static 类型
  6. ThreadLocal 中保存数据, 在线程销毁后, 会自动释放

ThreadLocal时序图

image-20220403160618777

2.快速入门ThreadLocal

T类

public class T {
    public static ThreadLocal threadLocal1 = new ThreadLocal();

    public static class MyThread implements Runnable{

        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            System.out.println("当前线程,"+name);
            /**
             *     public void set(T value) {
             *          //1.获取到当前线程
             *         Thread t = Thread.currentThread();
             *
             *         //2.将线程和ThradLocal进行关联
             *         //ThreadLocalMap是ThradLocal的静态内部类,Thread类中定义了 ThreadLocal.ThreadLocalMap threadLocals字段
             *         //getMap(t);===>  return t.threadLocals;对Thread的threadLocals进行了赋值
             *         ThreadLocalMap map = getMap(t);
             *
             *         //3.如果map不为空将threadloal最为key,传入的对象作为value存入到map中
             *         if (map != null)
             *             map.set(this, value);
             *         else
             *         //4.如果map为空则创建map并赋值
             *             createMap(t, value);
             *     }
             */
            threadLocal1.set(new Dog("一口", 2));
            threadLocal1.set(new Pig("琪琪",20));
            new TService().update();
        }
    }

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

Dog

public class Dog {
    private String name;
    private Integer age;

    public Dog(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

TService

public class TService {

    public void update(){
        Thread thread = Thread.currentThread();
        System.out.println("当前线程,"+thread.getName());
        Object o = T.threadLocal1.get();
        System.out.println("TService 获取到对象="+o);
        new TDao().update();
    }
}

TDao

public class TDao {

    public void update() {
        Thread thread = Thread.currentThread();
        System.out.println("当前线程,"+thread.getName());
        Object o = T.threadLocal1.get();
        System.out.println("TDao 获取到对象="+o);

    }
}

测试结果

image-20220403161705040

Debug

image-20220403162134247

3.ThreadLocal 原理图

image-20220403164420460


标题:线程数据共享和安全 -ThreadLocal
作者:llp
地址:https://llinp.cn/articles/2022/04/03/1648975519082.html