ThreadLocal 是一种线程安全的数据容器,实现原理就是会在不同的线程保持单独存储变量。
ThreadLocalMap 是 ThreadLocal 内部的一个类,类似 HashMap,其中 key 是当前 ThreadLocal 对象的 Hash ,value 是 ThreadLocal 对象的存储的值。
其中 get() 方法,会先从当前线程对象活动 Thread.threadLocals 对象,它是一个 ThreadLocalMap 对象。简单来说,就是不同的线程保持单独保存自己线程的变量。
get方法
get()方法用于获取当前线程的变量,如下:
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;
}
}
return setInitialValue();
}
通用的会先获取 会先从当前线程对象活动 Thread.threadLocals 对象,然后从 ThreadLocalMap 对象获取当前线程存储的变量。
关于ThreadLocal的官方文档描述
Implements a thread-local storage, that is, a variable for which each thread has its own value.
All threads share the same ThreadLocal object, but each sees a different value when accessing it,
and changes made by one thread do not affect the other threads.
The implementation supports null values.
该段文字描述了ThreadLocal的用途:
1.对于同一个变量(即ThreadLocal中保存的变量)对于不同的线程其值是不同的.
2 所有线程共享一个ThreadLocal对象,但是访问ThreadLocal对象中的变量时得到不同的值
3 某个线程修改了ThreadLocal对象中的变量值时不会影响到其他线程.
举个例子:
1 主线程中建立一个ThreadLocal对象(mThreadLocal)
2 在主线程中调用mThreadLocal的set()方法向mThreadLocal中保存一个字符串变量
3 在两个子线程中调用mThreadLocal的set()方法向mThreadLocal中保存一个字符串变量
4 在主线程中调用mThreadLocal的get()方法获取到mThreadLocal中为主线程保存字符串变量,发现其值未变.
ThreadLocal的使用在Looper类中得到很好的体现.保证了每个线程和一个Looper一一对应,并且每个Looper之间不受影响.