涉及到类:Thread、ThreadLocal、ThreadLocalMap(ThreadLocal的内部类)
含义:这些变量与普通变量不同,每个访问一个线程(通过其get或set方法)的线程都有其自己的,独立初始化的变量副本。 ThreadLocal实例通常是希望将状态与线程关联的类中的私有静态字段(例如,用户ID或交易ID)
例子:
private static class ThreadA extends Thread {
@Override
public void run() {
// 每个访问一个线程(通过其get或set方法)的线程都有其自己的,独立初始化的变量副本
ThreadLocal<Integer> threadlocal = new ThreadLocal<Integer>();
threadlocal.set(1);
threadlocal.get();
}
}
源码解析如下:(每一个Thread维护着一个ThreadLocalMap)
class Thread{
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; // 用于继承
}
当ThreadLocal的set方法
class ThreadLocal{
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
// 如果THreadLocalMap为空,就新建一个
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals; // 获得当前线程维护的ThreadLocalMap
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
ThreadLocalMap的key是对应的ThreadLocal<>
class ThreadLocal{
public T get() {
Thread t = Thread.currentThread();
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;
}
}
// 如果没有ThreadLocalMap的初始值
return setInitialValue();
}
}
与线程生命状态相关的体现
class Thread{
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* Speed the release of some of these resources */
threadLocals = null; // 退出时销毁
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
}
ThreadLocal使用场景:
(1)使用实例:Handler、looper
class Looper{
// 获得每个线程独立的looper
private ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
// 新建looper其中维护着queue管理Messege,用于线程的通信
sThreadLocal.set(new Looper(quitAllowed));
}
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
}
(2)可用于静态方法在多线程中的调用,获得专属当前的线程的内存区域(变量),这个是静态变量无法实现,因为静态变量无法区分线程(Lopper实现方式一致)
public class Text {
private final static ThreadLocal<Integer> local = new ThreadLocal<Integer>(){
protected Integer initialValue() {
return 1;
}
};
public static int A() {
// 每一个线程都会有独立的一份变量
Integer integer = local.get();
local.set(++integer);
return integer;
}
}