判斷線程以及l(fā)ooper相關(guān)

該文主要用于自我總結(jié),提煉。語句未經(jīng)斟酌,存在冗余重復(fù)等情況。各人客官可移步個人主頁右下方的《原創(chuàng)技術(shù)博客》文集,里面是對外發(fā)布的一些技術(shù)博客。(咳咳,如果用的是移動設(shè)備,簡書好像還沒支持,只能自己找。。)
當(dāng)然也可繼續(xù)閱讀,如若有些地方生澀難懂。那。。那就給我發(fā)私信,我整理一下。( ●▽● )

判斷所在的線程是不是主線程

可以使用

  if (Looper.getMainLooper()==Looper.myLooper()){
            //是主線程
        }else {
            //不是主線程
        }

這里的Looper.getMainLooper()得到的就是主線程的Looper實例。這沒有什么好說的。因為主線程的Looper在UI線程創(chuàng)建的時候(app啟動的時候)就調(diào)用了

Looper.prepare();//初始化Looper對象
Looper.loop();//啟動Looper

所以說,主線程的looper實例肯定是有的,并且已經(jīng)運行了。
那么工作線程(異步線程)呢?不好意思,異步線程初始化時并沒有綁定一個looper實例:

Threads by default do not have a message loop associated with them. Of course, the method works

所以如果一個工作線程沒有綁定looper,那么Looper.myLooper()返回的結(jié)果將是null。如果想綁定一個looper線程,并讓它運行,就需要:

new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();//初始化Looper對象
                Looper.loop();//啟動Looper
                //做一些線程的其他邏輯
            }
        }).start();

我們看到上面Looper.myLooper(); Looper.prepare();Looper.loop();Looper的靜態(tài)方法中并沒有傳入指定線程,但是最終得到的就是所在線程的looper或操作所在線程的looper。這是怎么做到的呢?
這是因為在Looper內(nèi)部維護了一個ThreadLocal:

public class Looper {
 
    static final ThreadLocal<looper> sThreadLocal = new ThreadLocal<looper>();
 
    public static void prepare() {
       prepare(true);
    }
 
    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));
    }
    ...
}

我們知道,在某一個線程調(diào)用sThreadLocal.get()時,得到的是該線程的數(shù)據(jù)的looper。前面的提到的Looper.prepare()用來在本線程生成一個looper實例在這里的源碼中也體現(xiàn)出來了。就是new 一個looper,然后放到ThreadLocal中。并且保證了一個線程只能有一個looper實例。

todo

  • 在一個線程調(diào)用ThreadLocal的get/set方法,為什么得到的就是當(dāng)前thread的值?
    1. Thread currentThread = Thread.currentThread();這樣能得到當(dāng)前線程的信息。
    2. 然后根據(jù)當(dāng)前線程的信息去ThreadLocal中拿線程對應(yīng)的值??梢詫hreadLocal理解為一塊存儲區(qū),將這一大塊存儲區(qū)分割為多塊小的存儲區(qū),每一個線程擁有一塊屬于自己的存儲區(qū),那么對自己的存儲區(qū)操作就不會影響其他線程。對于ThreadLocal,則每一小塊存儲區(qū)中就保存了與特定線程關(guān)聯(lián)的Looper。
  • looper的looper()方法做了什么工作?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容