Thread with Looper

Looper与线程之间的关系:

一直没有搞得很清楚,今天有时间,翻了一下源码,记录过程

 

/*
 * class : Looper
 */
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

请注意, sThreadLocal是一个static对象, 所有的Looper将共用一个sThreadLocal对象

 

当我们想为自己的进程创建自己的Looper的时候,应该调用下面这个函数,我们看看这个函数做了些什么:

/*
 * class : Looper
 */
private static void prepare(boolean quitAllowed) {

      //先看看当前线程是否已经有了自己的Looper,有的话将抛出异常。

     //第一次将获取null
       if (sThreadLocal.get() != null) {
           throw new RuntimeException("Only one Looper may be created per thread");
       }

      //没有的话则创建一个新的Looper,并将这个新的Looper通过sThreadLocal与当前线程绑定
       sThreadLocal.set(new Looper(quitAllowed));
}

 

/*
 * class : ThreadLocal
 */
public void set(T value) {
     //获取当前线程对象
     Thread t = Thread.currentThread();
    //获取当前线程的threadLocals成员变量,其类型是ThreadLocal.ThreadLocalMap
     ThreadLocalMap map = getMap(t);
     if (map != null)

         //this : sThreadLocal,ThreadLocal<Looper>的对象,请记住sThreadLocal是一个静态对象

         //value : Looper的对象
         map.set(this, value)
     else
         createMap(t, value);
}

 

/*
 * class : ThreadLocal
 */
ThreadLocalMap getMap(Thread t) {
     return t.threadLocals;
}

/*
 * class : Thread
 */
ThreadLocal.ThreadLocalMap threadLocals = null;

 

/*
 * class : ThreadLocalMap
 */
private void set(ThreadLocal key, Object value) {

        // We don't use a fast path as with get() because it is at
        // least as common to use set() to create new entries as
        // it is to replace existing ones, in which case, a fast
        // path would fail more often than not.

        Entry[] tab = table;
        int len = tab.length;
        int i = key.threadLocalHashCode & (len-1);

       //遍历整个table

        for (Entry e = tab[i];e != null;e = tab[i = nextIndex(i, len)]) {
            ThreadLocal k = e.get();

            //如果已经存在,则更新

            if (k == key) {
                e.value = value;
                return;
            }

           //如果table是空项,则使用key和value更新

            if (k == null) {
                replaceStaleEntry(key, value, i);
                return;
            }
        }

        tab[i] = new Entry(key, value);
        int sz = ++size;
        if (!cleanSomeSlots(i, sz) && sz >= threshold)
            rehash();
}

 

//这里给出Entry的定义

/*
  * class : ThreadLocalMap
  */

static class Entry extends WeakReference<ThreadLocal> {
        /** The value associated with this ThreadLocal. */
        Object value;

        Entry(ThreadLocal k, Object v) {
            super(k);
            value = v;
        }
}

 

整个流程看完下来,整个设计就比较清楚了。

1 每个线程都有ThreadLocal.ThreadLocalMap threadLocals = null;这样一个成员变量,这个变量的用途就在于维护各线程自有的对象的

2 threadLocals对应有一个Entry的table,

3 Looper只是某一种每个线程需要维护的对象,所以它将是Entry table的一项。其中,以ThreadLocal<Looper>类型的对象sThreadLocal为key,以Looper对象为value。

   如果还有其他的需要每个线程维护的对象,将与Looper类似。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值