线程数据共享和安全 -ThreadLocal

Posted Al_tair

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程数据共享和安全 -ThreadLocal相关的知识,希望对你有一定的参考价值。

ThreadLocal

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

线程数据共享和安全 - ThreadLocal

概述

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

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

代码示例

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);
        
        */
    

以上是关于线程数据共享和安全 -ThreadLocal的主要内容,如果未能解决你的问题,请参考以下文章

多线程一共就俩问题:1.线程安全(访问共享数据) 2.线程通信(wait(),notify())

线程共享数据的安全问题

线程安全

可重入函数与线程安全

线程安全

线程安全