JavaSE-多线程(14)- ThreadLocal 使用及源码解析
ThreadLocal 称为线程变量,在 ThreadLocal 中定义的变量被当前线程独有,看下例:
类 ThreadLocalTest 中 有一个ThreadLocal 属性,它用来保存 User 对象,线程 t1 和线程 t2 各自调用 ThreadLocalTest setUser 方法给 ThreadLocal 赋值,然后调用 run 方法取出 ThreadLocal 中的User对象,从输出结果中可以看出,t1 t2 中的属性相互不影响。
public class ThreadLocalTest {
private static ThreadLocal<User> tl = new ThreadLocal<>();
public void setUser(User user) {
tl.set(user);
}
public User getUser() {
return tl.get();
}
void run(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + this.getUser().getName());
}
public static void main(String[] args) {
ThreadLocalTest threadLocalTest = new ThreadLocalTest();
Thread t1 = new Thread(() -> {
threadLocalTest.setUser(new User("张三"));
threadLocalTest.run();
});
t1.setName("t1");
t1.start();
Thread t2 = new Thread(() -> {
threadLocalTest.setUser(new User("李四"));
threadLocalTest.run();
});
t2.setName("t2");
t2.start();
}
}
class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
t1 张三
t2 李四`
ThreadLocal 方法解析
set 方法
从 set 方法中我们只能看出,ThreadLocal set 方法将变量的值存放到 ThreadLocalMap 键值对中,如果 ThreadLocalMap 为空则通过 createMap 方法创建
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
getMap 方法
getMap 方法形参为 Thread ,一眼可以看出 threadLocals 为 Thread 的属性
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
Thread 类
public class Thread implements Runnable {
ThreadLocal.ThreadLocalMap threadLocals = null;
}
createMap 方法
创建 ThreadLocalMap 并将值赋值给 Thread threadLocals 属性
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
从以上分析不难看出,线程变量的本质就是每个线程都维护了一份自己线程变量的 Map
ThreadLocal 与 Synchronized 的区别
- Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。
- Synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。
参考:https://blog.csdn.net/u010445301/article/details/111322569