解决的问题是维护每个线程独立的对象。防止多线程同时操作对象造成互相干扰!
疑问
不同线程和ThreadLocal之间是如何相互持有的
- Thread类中维护的是一个ThreadLocalMap对象。
- ThreadLocalMap 在ThreadLocal中定义,实际就是维护了一个 Entry[]数组。
- Enter对象继承自WeakReference<ThreadLocal>,实际就是一个Threadlocal指向一个Object对象
- 当ThreadLocal调用get或者set方法时,会拿到Thread中的ThreadLocalMap对象,判断ThreadLocalMap对象是否为空,如果为空就new 一个新的ThreadLocalMap,此时键为当前ThreadLocal,值为null或者set设置进去的值;
给我的感觉:
- ThreadLocal就是一个管理ThreadLocalMap和Thread的类。ThreadLocal通过Thread.currentThread()获取线程对象。在通过线程对象拿到ThreadLocalMap
- ThreadLocalMap 把每一个ThreadLocal和每一个Object对象关联
- 每个Thread对应一个ThreadLocalMap
为啥要用一个ThreadLocalMap呢?这个里面是一个数组,而不用一个Entry对象就行?
我很疑惑这个问题,不是每一个线程都对应与一个ThreadLocalMap么?然后ThreadLocal拿到对应的Value值。
最后,我猜测是不是用于多个ThreadLocal的情况。
Android中用到ThreadLocal的地方
Looper 对象
static final 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");
}
sThreadLocal.set(new Looper(quitAllowed));
}
每次我们需要new 一个Handler的时候,其实都默认有一个Looper对象,这个对象都是通过sThreadLocal获取的。
public Handler(Callback callback, boolean async) {
****
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
****
}
// Looper.class
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
Logger开源库
在Logger开源库中也用到了ThreadLocal,保存的是TAG字符串。
写着写着又开始有点糊涂。看来还是要找点场景或案例实战一下