一、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**也可以通过**装苹果口袋的标签**找**小伙子A身上的口袋**找到自己口袋里的**苹果数**,当然这个数和小伙子A没关系。