ThreadLocal介绍

作者: 选一个昵称这么难 | 来源:发表于2017-09-06 17:19 被阅读296次

我们在说明handler原理和AsyncTask原理的时候都提到了ThreadLocal,当时没有细说,现在来介绍一下这个类
ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对于其它线程来说无法获取到数据.
什么意思?看代码更明白

public class MainActivity extends AppCompatActivity {

    //这里的泛型我们使用String,具体使用什么跟实际需求有关
    private ThreadLocal<String> threadLocal;
    private ThreadLocal<Integer> threadLocal2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        threadLocal = new ThreadLocal<>();
        threadLocal2 = new ThreadLocal<>();
        threadLocal.set("main");
        final Thread thread1 = new Thread(){
            @Override
            public void run() {
                threadLocal.set("1");
                threadLocal2.set(1111111);
                System.out.println(Thread.currentThread().getName()+"   :"+threadLocal.get());
                System.out.println(Thread.currentThread().getName()+"   :"+threadLocal2.get());
            }
        };

        final Thread thread2 = new Thread(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"   :"+threadLocal.get());
            }
        };

        thread1.setName("线程1");
        thread2.setName("线程2");
        thread1.start();
        thread2.start();
        System.out.println(Thread.currentThread().getName()+"   :"+threadLocal.get());
    }
}

查看结果:

System.out: 线程1   :1
System.out: main   :main
System.out: 线程2   :null
System.out: 线程1   :1111111

分析:虽然只有一个ThreadLocal实例,但是我们在不同线程为其赋值,然后在各自线程得到自己赋的值,这就很好的说明了ThreadLocal的特点
线面通过源码看看为什么会这样
先看set()方法

public void set(T value) {
        Thread t = Thread.currentThread();
        //getMap()方法就一句话:t.threadLocals,这个值默认是null
        //每个线程都维护了一个ThreadLocalMap,简单说ThreadLocalMap就是一个最终用来存储的容器
        ThreadLocalMap map = getMap(t);
        if (map != null)
            //key值是ThreadLocal对象,因为我们可以创建多个ThreadLocal对象来存储不同的数据,
            // value是设置的值
            map.set(this, value);
        else
            //创建ThreadLocalMap并存储
            createMap(t, value);
    }

然后看看get()方法

public T get() {
        Thread t = Thread.currentThread();
        //获取当前线程的存储容器
        ThreadLocalMap map = getMap(t);
        //不为空说明已经存储过值了,然后取值
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        //如果还没设置过值,则返回一个初始化的值
        return setInitialValue();
    }

看到这,应该明白ThreadLocal的奥秘了吧

相关文章

  • 大话 ThreadLocal

    概述 ThreadLocal 介绍 ThreadLocal 关键方法讲解 ThreadLocalMap 内部类介绍...

  • ThreadLocal原理介绍以及内存泄漏分析

    ThreadLocal简单介绍 ThreadLocal同ReentrantLock,CyclicBarrier等都...

  • Looper场景ThreadLocal原理分析

    ThreadLocal介绍 ThreadLocal支持泛型,ThreadLocal,T代表的是线程本地变量,...

  • 聊一聊我眼中的ThreadLocal(面试题形式总结)

    这篇总结一下 ThreadLocal,主要的议题有: ThreadLocal 介绍 ThreadLocal 实现原...

  • ThreadLocal介绍

    ThreadLocal简介 ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数...

  • ThreadLocal介绍

    我们在说明handler原理和AsyncTask原理的时候都提到了ThreadLocal,当时没有细说,现在来介绍...

  • ThreadLocal介绍

    ThreadLocal,顾名思义,其存储的内容是线程本地的,私有的,我们常用来存储和维护一些资源或者变量,以避免线...

  • ThreadLocal介绍

    ThreadLocal 能做什么 ThreadLocal 是 JDK 提供的一个工具类,它可以为每个使用它的线程创...

  • 介绍ThreadLocal

    1、概览 在本文中,我们将研究下ThreadLocal。ThreadLocal为我们提供了为当前线程单独保存数据的...

  • ThreadLocal介绍

    1. 简单使用 可以看到,同一个线程中设置完userId,在线程中的其他地方可以读取出来使用 2. 实现原理 我们...

网友评论

    本文标题:ThreadLocal介绍

    本文链接:https://www.haomeiwen.com/subject/xqjvjxtx.html