ThreadLocal
大家好呀,我是小笙!这部分是我学习ThreadLocal的笔记
线程数据共享和安全 - ThreadLocal
概述
ThreadLocal是一个将在多线程中为每一个线程创建单独的变量副本的类; 当使用ThreadLocal来维护变量时, ThreadLocal会为每个线程创建单独的变量副本, 避免因多线程操作共享变量而导致的数据不一致的情况
每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数 据,就需要使用多个 ThreadLocal 对象实例
代码示例
public class Dog {}
// ThreadLocalDemo
public class ThreadLocalDemo implements Runnable{
public static ThreadLocal<Object> threadLocal= new ThreadLocal<>();
public static void main(String[] args) {
// 创建进程
new Thread(new ThreadLocalDemo()).start();
}
@Override
public void run() {
Dog dog = new Dog();
threadLocal.set(dog);
System.out.println("ThreadLocalDemo: " + Thread.currentThread().getName());
new Service().update();
}
}
// Service
public class Service {
public void update() {
Object o = ThreadLocalDemo.threadLocal.get();
System.out.println(o.getClass()); // threadLocal.Dog
String name = Thread.currentThread().getName();
System.out.println("在 Service 的 update() 线程 name= " + name);
new Dao().update();
}
}
// Dao
public class Dao {
public void update() {
Object o = ThreadLocalDemo.threadLocal.get();
System.out.println(o.getClass()); // threadLocal.Dog
String name = Thread.currentThread().getName();
System.out.println("在 Dao 的 update() 线程是= " + name);
}
}
源码分析
// ThreadLocal.get()方法
public T get() {
// 获取当前进程t
Thread t = Thread.currentThread();
// 从容器map中获取该线程的threadLocals
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
// ThreadLocal.set(数据)方法
public void set(T value) {
// 获取当前进程t
Thread t = Thread.currentThread();
// 从容器map中获取该线程的threadLocals
ThreadLocalMap map = getMap(t);
/*
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
*/
if (map != null) {
// 如果存在,则覆盖该 threadLocals对象对应的原来数据(可以是对象)
map.set(this, value);
} else {
// 如果不存在,则创建t.threadLocals,存入ThreadLocalMap对象
// key:this(调用该方法的threadLocal对象)value:需要存入的数据
createMap(t, value);
/*
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
*/
}
}