Android ThreadLocal的学习和理解

2017-08-23  本文已影响0人  w小强

解决的问题是维护每个线程独立的对象。防止多线程同时操作对象造成互相干扰!

疑问

不同线程和ThreadLocal之间是如何相互持有的

  1. Thread类中维护的是一个ThreadLocalMap对象。
  2. ThreadLocalMap 在ThreadLocal中定义,实际就是维护了一个 Entry[]数组。
  3. Enter对象继承自WeakReference<ThreadLocal>,实际就是一个Threadlocal指向一个Object对象
  4. 当ThreadLocal调用get或者set方法时,会拿到Thread中的ThreadLocalMap对象,判断ThreadLocalMap对象是否为空,如果为空就new 一个新的ThreadLocalMap,此时键为当前ThreadLocal,值为null或者set设置进去的值;
ThreadLocal.get()方法.png ThreadLocal.set(T value).png 对Thread中的ThreadLocalMap赋值.png

给我的感觉:

  1. ThreadLocal就是一个管理ThreadLocalMap和Thread的类。ThreadLocal通过Thread.currentThread()获取线程对象。在通过线程对象拿到ThreadLocalMap
  2. ThreadLocalMap 把每一个ThreadLocal和每一个Object对象关联
  3. 每个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字符串。

LoggerPrinter.class.png

写着写着又开始有点糊涂。看来还是要找点场景或案例实战一下

上一篇下一篇

猜你喜欢

热点阅读