美文网首页
ThreadLocal介绍

ThreadLocal介绍

作者: 豆小豆33 | 来源:发表于2018-03-25 14:24 被阅读0次

ThreadLocal简介

ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对于其它线程来说无法获取到数据。
一般来说,当某些数据是以线程为作用域并且不同线程具有不同的数据副本的时候,就可以考虑采用ThreadLocal。
下面首先使用ThreadLocal举一个例子:

final ThreadLocal<Boolean> threadLocal = new ThreadLocal<>();
threadLocal.set(false);
Log.i("ThreadLocal","Thread name "+ Thread.currentThread().getName() +"ThreadLocal Value : " + threadLocal.get());
new Thread("Thread 2"){

      @Override
      public void run() {
           threadLocal.set(true);
           Log.i("ThreadLocal","Thread name "+ Thread.currentThread().getName() +"ThreadLocal Value : " + threadLocal.get());
      }
}.start();
new Thread("Thread 3"){
       @Override
       public void run() {
             Log.i("ThreadLocal","Thread name "+ Thread.currentThread().getName() + "ThreadLocal Value : " + threadLocal.get());
       }
}.start();

=======================
Thread name mainThreadLocal Value : false
Thread name Thread 2ThreadLocal Value : true
Thread name Thread 3ThreadLocal Value : null

通过上面的例子,我们会发现。虽然是同一个ThreadLocal对象。但是不同线程中,我们获取到的参数不一致。而这也就是ThreadLocal的精髓所在。也就是我们上面说到的,ThreadLocal的作用域在于线程。
注意:ThreadLocal并不是为了实现线程间的数据共享。他是为了实现不同线程的数据独立。

解析ThreadLocal实现

  • 首先我们看一下ThreadLocal提供的接口:


    image.png

    是的你没看错,ThreadLocal之提供了这三个对外使用的方法。
    那么我们就对set进行分析。

  • set方法
    public void set(T value) {
        // 获得当前线程
        Thread t = Thread.currentThread();
        // 通过当前线程获取一个ThreadLocalMap对象
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

从上面的方法细节可以看出来,ThreadLocalMap是关键,那么让我们看一看ThreadLocalMap对象的内部是什么。
截取了ThreadLocalMap的一段代码

    static class ThreadLocalMap {
        
        private Entry[] table;

        static class Entry extends WeakReference<ThreadLocal<? {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
   }

首先说明一点,这里的ThreadLocalMap是ThreadLocal的内部类。
其次根据代码我们可以发现,其实ThreadLocalMap里面声明了一个Entry的数组。而Entry包含两个参数,分别是ThreadLocal和Value。
看到这里,很多内容已经很明显了。
我们对ThreadLocal设置参数的时候,其实是将信息设置到ThreadLocalMap这个对象里,key是ThreadLocal对象本身,value是外面传入的值。
疑问:小编看到这里的时候,有一个疑问点在于,如果key是ThreadLocal的话,ThreadLocal对象是唯一的,又是怎么实现多线程间的数据存储的呢?
所以这个时候,我们再回到ThreadLocal中的set方法。

    public void set(T value) {
        // 获得当前线程
        Thread t = Thread.currentThread();
        // 通过当前线程获取一个ThreadLocalMap对象
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }


    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

针对上面提出的疑问点,既然ThreadLocal是唯一的,那么读取的ThreadLocalMap肯定就是针对线程的了。
通过createMap我们可以发现,ThreadLocalMap这个对象的引用,来自Thread。
我们再来看一下Thread的相关源码:

class Thread implements Runnable {
    ThreadLocal.ThreadLocalMap threadLocals = null;
}

果然,ThreadLocal里面有一个ThreadLocalMap的引用。
从这里就可以看出,每一个Thread都有一个ThreadLocalMap引用。我们的ThreadLocal就通过每一个Thread对象中的map引用进行数据存储。
Key是ThreadLocal本身,value就是传入参数。
通过这种方式,就很容易实现了不同线程间的数据独立存储。
好啦,今天这篇文章到此为止。如果有不明白的,或者小编有哪些地方说的不到位的,欢迎留言。每一条留言小编都会看。

相关文章

  • 大话 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/fbphcftx.html