文章目录
ThreadLocal的使用
一、介绍
1. 作用
-
可以解决多线程的数据安全问题,将当前线程关联一个数据(可以是普通变量,可以是对象,也可以是数组,集合)
-
原理
-
在共享内存中提供该变量的副本,每个线程都可以独立的使用自己的副本,而不会影响其他线程所对应的副本
-
图示
-
2. 特点
- ThreadLocal 可以为当前线程关联一个数据;它可以像 Map 一样存取数据,但是只需要存取value即可,key为当前线程,value为关联的值
- ThreadLocal中定义了set、get、remove方法,用来关联 / 取出 / 移除数据
- 每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个ThreadLocal 对象实例;关联多个数据时,后者会覆盖前者
- ThreadLocal 中保存数据,在线程销毁后,会由 JVM 虚拟机自动释放
二、代码示例
public class ThreadLocalTest {
public static void main(String[] args) throws InterruptedException {
final ThreadLocal<Integer> th = new ThreadLocal<Integer>();
//t1线程
new Thread(new Runnable() {
@Override
public void run() {
try {
th.set(100); //给t1线程的副本赋值
System.out.println("t1线程赋予的值:" + th.get());
Thread.sleep(2000); //t1线程睡眠2秒,睡眠的时间段内t2线程会运行
System.out.println("t1线程获取的值:"+th.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(1000);
//t2线程
new Thread(new Runnable() {
@Override
public void run() {
Integer ele = th.get(); //t2线程尝试从自己的副本中取值(此时为null,与t1的副本无关系)
System.out.println("t2线程获取的值:" + ele);
th.set(200); //t2线程给自己的副本赋值
System.out.println("t2线程给副本赋值后获取的值:"+th.get()); //t2线程从自己的副本中获取值
}
}).start();
}
}
运行结果: