通過Java的ThreadLocal來了解Handler的線程綁定

參考資料:

ThreadLocal:https://www.cnblogs.com/coshaho/p/5127135.html

Handler:https://www.jianshu.com/p/3d8f7ec1017a


0.ThreadLocal和Thread的關係

每個Thread中都有一個存儲ThreadLocal的Map對象,這個Map不是使用的集合類中的Map,用的是一個叫做“ThreadLocalMap”(從名字可以明顯看出來它的作用了)的類來存儲。ThreadLocalMap是一個可以存儲key-value的map,key就是ThreadLocal,value就是要存儲的跟ThreadLocal對應的值。

這裏的ThreadLocalMap是ThreadLocal的“基友類”。

下圖看下兩者關係

1.線程綁定

問起Handler的原理,會提起Looper和MessageQueue跟線程綁定,balabala。

這裏實現線程綁定就是使用的Thread中的ThreadLocalMap來實現。

如何使用ThreadLocal呢。首先需要一個Manager類來持有一個ThreadLocal<T>的實例。不同的Thread將這個實例和想存儲的值保存起來就好咯。ThreadLocal提供了set、get等等方法來方便獲取或者保存當前運行線程(Thread.currentThread()可以獲取當前線程)對應的存儲值。這樣爲了不同的功能,我們可以定義不同的ThreadLocal,而且互不干擾。

線程綁定,直接寫成Map<Thread, value>不就可以實現嗎,爲什麼要寫得如此複雜。

這種存儲結構的好處:

1、線程死去的時候,線程共享變量ThreadLocalMap則銷燬。

2、ThreadLocalMap<ThreadLocal,Object>鍵值對數量爲ThreadLocal的數量,一般來說ThreadLocal數量很少,相比在ThreadLocal中用Map<Thread, Object>鍵值對存儲線程共享變量(Thread數量一般來說比ThreadLocal數量多),性能提高很多。

摘自:https://www.cnblogs.com/coshaho/p/5127135.html

2.Handler

 Hander有一個相關類爲Looper,這個就是上面所說的Manager類。

 Looper有幾個屬性值:

// 存儲Looper的ThreadLocal,可以看出Looper不僅充當Manager,還作爲基礎數據類(存儲MessageQueue等信息)
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

// 主線程的Looper
private static Looper sMainLooper;

// Looper對應的MessageQueue
final MessageQueue mQueue;

可以看出Looper不僅充當Manager,還作爲基礎數據類(存儲MessageQueue等信息),通過sThreadLocal,實現了線程和Looper的綁定。

Looper有個重要方法:

    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

由此,大部分Looper的代碼基本上可以知道是什麼意思了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章