ThreadLocal理解

Easter79
• 阅读 649
  1. 使用ThreadLocal的时候我们保证了每个线程可以隔离使用对象,避免线程间的数据干扰。

常用例子

public class ThreadLocalTest {

    public static void main(String[] args) throws InterruptedException {
        ThreadLocal tl=new ThreadLocal();
        tl.set("123");
        System.out.println(Thread.currentThread()+":"+tl.get());
        
        Thread t=new Thread(
            new  Runnable() {
                public void run() {
                   tl.set("456"); 
                   System.out.println(Thread.currentThread()+":"+tl.get());
                }
            });
        t.start();
        Thread.sleep(1000);
        System.out.println(Thread.currentThread()+":"+tl.get());
}}

结果:

Thread[main,5,main]:123
Thread[Thread-0,5,main]:456
Thread[main,5,main]:123

从上面的例子可以看出来,每个线程保存的对象是隔离的!

  1. 代码分析

    下面是Thread里面定义的对象,它的声明是在ThreadLocal里面的一个静态子类对象 ThreadLocal.ThreadLocalMap threadLocals = null;

    这里是ThreadLocal的对象定义 static class ThreadLocalMap { static class Entry extends WeakReference<ThreadLocal> { /** The value associated with this ThreadLocal. */ Object value; //可以看出key为当前的ThreadLocal对象,value为保存的数据对象 Entry(ThreadLocal k, Object v) { super(k); value = v; } } }

下面set/get/getMap/createMap方法,可以存储数据

public void set(T value) {
        //获取当前线程
        Thread t = Thread.currentThread();
        //根据当前的线程获取数据
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
    
public T get() {
       //获取当前线程
        Thread t = Thread.currentThread();
        //根据当前的线程获取数据
        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();
    }    
    
    /**
     * 这里可以看出返回的数据是当前的线程变量
     */
 ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
  }    
  
 void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
}  


从上面可以看出写的代码示例,返回值是不同的因为线程是独立的,
独立线程会有自己的单独数据存储map,
至于ThreadLocal当作key是为了防止多个ThreadLocal在同一个线程当中做区分
  1. ThreadLocal做保存数据的key唯一性

    //ThreadLocal类中有一个被final修饰的类型为int的threadLocalHashCode,它在该ThreadLocal被构造的时候就会生成,相当于一个ThreadLocal的ID private final int threadLocalHashCode = nextHashCode(); //threadLocalHashCode值来源于这里 private static AtomicInteger nextHashCode =new AtomicInteger(); private static final int HASH_INCREMENT = 0x61c88647; private static int nextHashCode() { return nextHashCode.getAndAdd(HASH_INCREMENT); }

点赞
收藏
评论区
推荐文章
待兔 待兔
3年前
ThreadLocal源码分析
最近在学多线程并发的知识,发现好像ThreadLoca还挺重要,决定看看源码以及查找各方资料来学习一下。ThreadLocal能够提供线程的局部变量,让每个线程都可以通过set/get来对这个局部变量进行操作,不会和其它线程的局部变量进行冲突,实现了线程的数据隔离。首先是ThreadLocal的结构:每个Thread维护一个ThreadLocalMap,这个
ThreadLocal源码解析及实战应用
ThreadLocal是一个关于创建线程局部变量的类。通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。ThreadLocal在设计之初就是为解决并发问题而提供一种方案,每个线程维护一份自己的数据,达到线程隔离的效果。
Easter79 Easter79
3年前
TransmittableThreadLocal在使用线程池等会缓存线程的组件情况下传递ThreadLocal
1、简介TransmittableThreadLocal是Alibaba开源的、用于解决“在使用线程池等会缓存线程的组件情况下传递ThreadLocal”问题的InheritableThreadLocal扩展。若希望TransmittableThreadLocal在线程池与主线程间传递,需配合_TtlRunnab
Wesley13 Wesley13
3年前
Java多线程与并发之ThreadLocal原理解析
1\.ThreadLocal是什么?使用场景ThreadLocal简介ThreadLocal是线程本地变量,可以为多线程的并发问题提供一种解决方式,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,
Wesley13 Wesley13
3年前
JAVA ThreadLocal对象浅析
最近在开发过程中,在做一个字典项服务的时候,最开始采用了ThreadLocal对象来缓存数据。在使用ThreadLocal过程中遇到一些问题,这里和大家分享一下。一、什么是ThreadLocal?顾名思义它是localvariable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值
Wesley13 Wesley13
3年前
Java并发编程的艺术笔记(四)——ThreadLocal的使用
ThreadLocal,即线程变量,是一个以ThreadLocal对象为键、任意对象为值的存储结构。这个结构被附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值。目的就是为了让线程能够有自己的变量可以通过set(T)方法来设置一个值,在当前线程下再通过get()方法获取到原先设置的值
Wesley13 Wesley13
3年前
Java多线程与并发之ThreadLocal
1\.ThreadLocal是什么?使用场景ThreadLocal简介ThreadLocal是线程本地变量,可以为多线程的并发问题提供一种解决方式,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,
Wesley13 Wesley13
3年前
JAVA基础系列:ThreadLocal
1. 思路1.什么是ThreadLocal?ThreadLocal类顾名思义可以理解为线程本地变量。也就是说如果定义了一个ThreadLocal,每个线程往这个ThreadLocal中读写是线程隔离,互相之间不会影响的。它提供了一种将可变数据通过每个线程有自己的独立副本从而实现线程封闭的机制。2.它大致的实现
Easter79 Easter79
3年前
ThreadLocal 详解
概念ThreadLocal用于提供线程局部变量,在多线程环境可以保证各个线程里的变量独立于其它线程里的变量。也就是说ThreadLocal可以为每个线程创建一个【单独的变量副本】,相当于线程的privatestatic类型变量。使用示例publicclassThreadLocalTest{
Easter79 Easter79
3年前
ThreadLocal设计模式
ThreadLocal设计模式使用的也很频繁,会经常在各大框架找到它们的踪影,如struts2以及最近正在看的SpringAOP等。ThreadLocal设计模式也有很多误解,我的理解是(1)ThreadLocal所操作的数据是线程间不共享的。它不是用来解决多个线程竞争同一资源的多线程问题。(2)ThreadLocal所操作的数据主要
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k