ThreadLocal
概述
ThreadLocal实例仅作为线程局部变量的操作类,以及线程存储局部变量时的Key。真正的线程局部变量是存储在各自线程的本地,通过Thread类中的ThreadLocal.ThreadLocalMap threadLocals
进行存储。
若希望在线程本地存储多个局部变量需要使用多个ThreadLocal实例进行操作。
ThreadLocal源码示例
-
set(T v)方法
通过Thread.currentThread()获取当前的线程实例,然后获取当前线程实例里的ThreadLocal.ThreadLocalMap threadLocals
,若不存在该集合对象则创建。最后,将当前ThreadLocal实例作为Key,将参数值v存储当前线程的threadLocals
集合中。即var3.set(this, var1);
-
get()方法
通过Thread.currentThread()获取当前的线程实例,然后获取当前线程实例里的ThreadLocal.ThreadLocalMap threadLocals
,若该集合对象不为空,则用当前ThreadLocal实例作为Key,从集合对象中获取之前存储的值。即var3 = var2.getEntry(this);
public T get() {
Thread var1 = Thread.currentThread();
ThreadLocal.ThreadLocalMap var2 = this.getMap(var1);
if (var2 != null) {
ThreadLocal.ThreadLocalMap.Entry var3 = var2.getEntry(this);
if (var3 != null) {
Object var4 = var3.value;
return var4;
}
}
return this.setInitialValue();
}
private T setInitialValue() {
Object var1 = this.initialValue();
Thread var2 = Thread.currentThread();
ThreadLocal.ThreadLocalMap var3 = this.getMap(var2);
if (var3 != null) {
var3.set(this, var1);
} else {
this.createMap(var2, var1);
}
return var1;
}
public void set(T var1) {
Thread var2 = Thread.currentThread();
ThreadLocal.ThreadLocalMap var3 = this.getMap(var2);
if (var3 != null) {
var3.set(this, var1);
} else {
this.createMap(var2, var1);
}
}
public void remove() {
ThreadLocal.ThreadLocalMap var1 = this.getMap(Thread.currentThread());
if (var1 != null) {
var1.remove(this);
}
}
ThreadLocal.ThreadLocalMap getMap(Thread var1) {
return var1.threadLocals;
}
void createMap(Thread var1, T var2) {
var1.threadLocals = new ThreadLocal.ThreadLocalMap(this, var2);
}
Thread源码示例
Thread类使用ThreadLocal.ThreadLocalMap threadLocals
集合对象盛装线程局部变量。
public class Thread implements Runnable {
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
private volatile String name;
private int priority;
private Thread threadQ;
private long eetop;
/* Whether or not to single_step this thread. */
private boolean single_step;
/* Whether or not the thread is a daemon thread. */
private boolean daemon = false;
/* JVM state */
private boolean stillborn = false;
/* What will be run. */
private Runnable target;
/* The group of this thread */
private ThreadGroup group;
/* The context ClassLoader for this thread */
private ClassLoader contextClassLoader;
/* The inherited AccessControlContext of this thread */
private AccessControlContext inheritedAccessControlContext;
/* For autonumbering anonymous threads. */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;