赞
踩
ThreadLocal: 通常被称作线程本地变量或者线程本地存储。其含义是ThreadLocal为变量在每个线程中都创建一个副本,则每个线程可以访问自身内部的副本变量。
概念总是抽象而且晦涩的,我们从两个例子说起。
如下图,有个多层调用的情况,如果我们需要传递某个中间结果在这几层调用关系之间,应该怎么处理呢?
A.fun1()
之中将数据保存在单例类中,然后在之后的其他函数中操作该数据。如果是多线程的环境,如果同时有多个线程同时操作入口函数A.fun1()
,则单例保存的数据则会被污染。ThreadLocal
为该数据在每个线程中都创建一个副本,则线程之间则不会互相影响。如下代码,通过ThreadLocal,我们可以使数据在对象间/方法间进行传递。public class ThreadLocalDemo {
private ThreadLocal<Long> threadLocal = new ThreadLocal<>();
private void fun1() {
threadLocal.set(System.nanoTime());
System.out.println("fun1:" + threadLocal.get());
fun2();
}
private void fun2() {
System.out.println("fun2:" + threadLocal.get());
fun3();
}
private void fun3() {
System.out.println("fun3:" + threadLocal.get());
threadLocal.remove();
}
public static void main(String[] args) {
ThreadLocalDemo demo = new ThreadLocalDemo();
demo.fun1();
}
}
如果需要将一个单线程的应用移植到到多线程的环境下,就需要将共享的一些全局变量转换为ThreadLocal对象;这相当于ThreadLocal为每个线程都创建了一个该全局变量的副本。保证了其线程安全性。
但是,TheadLocal并不是解决高并发下共享资源的方式。大多数情况下,ThreadLocal存储的是一个new
的新对象。但是如果其存储一个对象的引用,也会面临资源竞争的情况。
static int a = 0;
,共有5个线程对其进行++操作,保险起见,我们对++
进行加锁(Sync)。这样在执行完之后,a == 5
,毫无疑问。 a =
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。