ThreadLocal说明

通常,程序中的对象在多线程下,数据都是竞争共享的。但是,有一个类例外,他生成的实例是线程私有的,ThreadLocal。ThreadLocal生成的对象,线程私有,这是怎么做到的呢?

先看个实例:

public class Test {

    private ThreadLocal<String> stringThreadLocal = new ThreadLocal<>() ;
    private ThreadLocal<String> stringThreadLocal2 = new ThreadLocal<>() ;

    public void print() {
        System.out.println("threadName:" + Thread.currentThread().getName() + ",value:" + stringThreadLocal.get());
        System.out.println("threadName:" + Thread.currentThread().getName() + ",value:" + stringThreadLocal2.get());
    }

    public void setValue(String value) {
        stringThreadLocal.set(value);
        stringThreadLocal2.set(value + "——2");
    }

    public static void main(String[] args) throws InterruptedException {

        Test test = new Test() ;
        test.setValue("test0");
        test.print();

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                test.setValue("test1");
                test.print();
            }
        }) ;
        thread1.start();

        Thread.sleep(1000);

        test.print();
    }
}

输出:

threadName:main,value:test0
threadName:main,value:test0——2
threadName:Thread-0,value:test1
threadName:Thread-0,value:test1——2
threadName:main,value:test0
threadName:main,value:test0——2

从输出结果,看出stringThreadLocal和stringThreadLocal2结果不同,大家可能好理解;但是线程main,和线程 Thread-0 从属性stringThreadLocal和stringThreadLocal2获取的值是不同的,就不是很好理解了。

其实Thread类有一个map,存放相同线程不同ThreadLocal对象对应的值(key为ThreadLocal,value为需要存储的值);ThreadLocal就是对线程Thread内部这个map的管理,不同的线程获取的map不同,不同的ThreadLocal获取的value也不同。

如下ThreadLocal源码:

public T get() {
    //  获取当前线程
    Thread t = Thread.currentThread();
    // 获取当前Thread的map
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        // 获取当前ThreadLocal对象对应的entry
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}
// 获取当前线程对应的map
ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}

public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}
时间: 2024-10-25 18:12:44

ThreadLocal说明的相关文章

Java中ThreadLocal的深入理解

官方对ThreadLocal的描述: "该类提供了线程局部(thread-local)变量.这些变量不同于它们的普通对应物,因为访问某个变量(通过其get或set方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本.ThreadLocal实例通常是类中的private static字段,它们希望将状态与某一个线程(例如,用户ID或事物ID)相关联." <Thinking in Java>中的描述: 防止任务在共享资源上产生冲突的第二种方式是根除对变量的共享.线程本地

java 之ThreadLocal

通过 ThreadLocal 能数据保存在一个线程中,而且不需要 lock 同步.理论上 ThreadLocal 可 以让一个变量在每个线程都有一个副本. ThreadLocal 常用来屏蔽线程的私有变量,例如"并 发事务"或者其他的资源.而且,它还被用来维护每个线程的计数器,统计,或者 ID 生成 器. 由ThreadLocal常用的get方法定义看: public T get() { Thread t = Thread.currentThread(); ThreadLocalMap

图解ThreadLocal

ThreadLocal ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序. 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本. 从线程的角度看,目标变量就象是线程的本地变量,这也是类名中"Local"所要表达的意思. 那么ThreadLocal是如何做到的呢?上图. 图没看懂?那我们来看一下源

Java中线程封闭之ThreadLocal

在访问共享数据时通常使用同步.若不使用同步则可以将对象封闭在一个线程中达到线程安全的目的,该方法称为线程封闭(Thread Confinement).其中实现线程封闭中规范的方法是使用ThreadLocal类.线程封闭技术一种常用的使用场景是在JDBC Connection对象. public class ConnectionHelper{private final static String URL = "";private final static ThreadLocal<C

ThreadLocal

为了防止内存泄露,一旦threadlocal完成任务,最好调用remove() 详见:ThreadLocal explained

并发编程(四):ThreadLocal从源码分析总结到内存泄漏

一.目录 1.ThreadLocal是什么?有什么用? 2.ThreadLocal源码简要总结? 3.ThreadLocal为什么会导致内存泄漏? 二.ThreadLocal是什么?有什么用? 引入话题:在并发条件下,如何正确获得共享数据?举例:假设有多个用户需要获取用户信息,一个线程对应一个用户.在mybatis中,session用于操作数据库,那么设置.获取操作分别是session.set().session.get(),如何保证每个线程都能正确操作达到想要的结果? /** * 回顾sync

从源码理解 ThreadLocal()

每一反应,使用Thread中定义一个成员变量来解决 线程局部变量问题: 为什么要使用ThreadLocal(),有什么好处: 单例的完整性: 解决了线程上下文中的变量传递问题,达到线程安全目的: ThreadLocal和synchronized的区别? ThreadLocal使用场景 待完成...

理解Java ThreadLocal

ThreadLocal是什么 早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序. ThreadLocal很容易让人望文生义,想当然地认为是一个"本地线程".其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些. 当使用ThreadLocal维护变量

我对ThreadLocal的理解

声明:小弟菜狗一个.对ThreadLocal的描写叙述和理解难免有所偏差 近期由于须要深入的了解android的handler消息机制而去查看了Looper的源代码.众所周知在主线程中是不须要在程序猿在代码新建一个Looper对象的,由于在主线程创建时它就被创建出来了.所以就好奇它是怎么被创建出来的然后发现它跟ThreadLocal 有关于是便查看了该类的一些资料,但还是不太理解.于是便尝试自己去看一下源代码,然后就有了对ThreadLocal一个又一次的认识.先贴出Looper的代码: pri

ThreadLocal实现原理

一.ThreadLocal介绍 这是一个线程的局部变量.也就是说,只有当前线程可以访问.既然是只有当前线程可以访问的数据,自然是线程安全的. 为每一个线程分配不同的对象,需要在应用层面保证.ThreadLocal只是起到了简单的容器作用. 二.实现原理 1. 我们需要关注的是ThreadLocal的set()方法和get()方法. set()方法 public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMa