ThreadLocal 是嘛玩意?

703 阅读2分钟

一、ThreadLocal简介

ThreadLocal叫做线程变量,给这么好的东西取这个么名的人也是...误导了我好久。不懂得看加粗部分 一下子就懂了。

它的作用为每一个线程创建一个副本

比如我在一个方法里创建一个全局的int 【苹果数量】=0

有A B两个线程访问,在各自的run()执行 "苹果数=苹果数+1".

那么A线程里打印出来的苹果数量可能是2。A想要的结果其实是苹果数是0,我+1后应该是1.这也就是多线程访问一个指导致的错乱。

如果定义的是一个ThreadLocal< int > 苹果数量 = new ThreadLocal< int >(); 那么A线程和B线程里的苹果数量都会是1


public class ThreadLocaDemo {

    private static ThreadLocal<String> localVar = new ThreadLocal<String>();

    static void print(String str) {
        //打印当前线程中本地内存中本地变量的值
        System.out.println(str + " :" + localVar.get());
        //清除本地内存中的本地变量
        localVar.remove();
    }
    public static void main(String[] args) throws InterruptedException {

        new Thread(new Runnable() {
            public void run() {
                ThreadLocaDemo.localVar.set("local_A");
                print("A");
                //打印本地变量
                System.out.println("after remove : " + localVar.get());

            }
        },"A").start();

        Thread.sleep(1000);

        new Thread(new Runnable() {
            public void run() {
                ThreadLocaDemo.localVar.set("local_B");
                print("B");
                System.out.println("after remove : " + localVar.get());

            }
        },"B").start();
    }
}

打印结果

A :local_A
after remove : null  
B :local_B
after remove : null

意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。


二、ThreadLocal与Synchronized的区别

两位都是来解决多线程并发绑定的,但有一个本质上的区别,就像治水大禹和他爹。

1、ThreadLocal为每一个线程都提供了变量副本,每个线程小伙子都有一台PS5游戏机,不用抢,互不干涉。也就是线程间数据隔离

Synchronized则是则是利用锁的机制,咱们只有一个PS5游戏机,先抢到的线程小伙子就玩通关了,然后给另外一个小伙子玩。就是让线程间进行共享

三、ThreadLocal与Thread,ThreadLocalMap之间的关系

thread就是小伙子

ThreadLocalMap就是小伙子身上的口袋

threadlocal就是装苹果口袋的标签

就是小伙子A通过装苹果口袋的标签小伙子A身上的口袋最后找到了自己口袋里的苹果数

小伙子B也可以通过装苹果口袋的标签小伙子B身上的口袋找到自己口袋里的苹果数,当然这个数和小伙子A没关系。

image.png