面試中關於執行緒原始碼相關的面試題

2021-10-02 16:50:45 字數 4839 閱讀 6221

關於執行緒方面的面試題,大部分都是概念題,我們需要大概的清楚這些概念,和面試官達成共識即可;

1 建立子執行緒時,子執行緒是得不到父執行緒的 threadlocal,有什麼辦法可以解決這個問題?

// 當父執行緒的 inheritablethreadlocals 的值不為空時

// 會把 inheritablethreadlocals 裡面的值全部傳遞給子執行緒

if (parent.inheritablethreadlocals != null)

this.inheritablethreadlocals =

threadlocal.createinheritedmap(parent.inheritablethreadlocals);

2 執行緒建立有幾種實現方式?

主要有三種,分成兩大類,第一類是執行緒沒有返回值,第二類是執行緒有返回值;

無返回值的執行緒有兩種寫法:

第一種是繼承 thread,可以這麼寫:

class mythread extends thread

}@test

public void extendthreadinit()

第二種是實現 runnable 介面,並作為 thread 構造器的入參,**如下:

thread thread = new thread(new runnable()  begin run",thread.currentthread().getname());

}});

// 開乙個子執行緒去執行

thread.start();

第三種:使用 callable 介面獲取futuretask 並將其作為thread構造器的入參:

如果需要子執行緒有返回值,需要使用 callable 介面,但 callable 介面是無法直接作為 thread 構造器的入參的,必須結合 futuretask 一起使用,可以這樣寫**:

@test

public void testthreadbycallable() throws executionexception, interruptedexception ",thread.currentthread().getname());

return result;

}});

new thread(futuretask).start();

log.info("返回的結果是 {}",futuretask.get());

}

3 執行緒 1 去等待執行緒 2 執行完成之後才能執行,如何去實現?

這裡考察的就是 thread.join 方法,我們可以這麼做:

@test

public void testjoin2() throws exception catch (interruptedexception e)

log.info("我是子執行緒 2,執行完成");

}});

thread thread1 = new thread(new runnable() catch (interruptedexception e)

log.info("我是子執行緒 1,執行完成");

}});

thread1.start();

thread2.start();

thread.sleep(100000);

}

4 守護執行緒和非守護執行緒的區別?

主要區別是,在 jvm 退出時,jvm 是不會管守護執行緒的,只會管非守護執行緒,如果非守護執行緒還有在執行的,jvm 就不會退出,如果沒有非守護執行緒了,但還有守護執行緒的,jvm 直接退出

5 如果我想在專案啟動的時候收集**資訊,請問是守護執行緒好,還是非守護執行緒好,為什麼?

如果需要在專案啟動的時候收集**資訊,就需要看收集工作是否重要了,如果不太重要,又很耗時,就應該選擇守護執行緒,這樣不會妨礙 jvm 的退出,如果收集工作非常重要的話,那麼就需要非守護程序,這樣即使啟動時發生未知異常,jvm 也會等到**收集資訊執行緒結束後才會退出,不會影響收集工作。

6 執行緒 start 和 run 之間的區別?

呼叫 thread.start 方法會開乙個新的執行緒,run 方法不會

7 thread、runnable、callable 三者之間的區別?

runnable 是無返回值任務介面,callable 是有返回值任務介面,runnable 和 callable 只是任務的定義,具體執行還需要靠 thread;

thread 實現了 runnable,本身就是 runnable,但同時負責執行緒建立、執行緒狀態變更等操作;如果任務需要跑起來,必須需要 thread 的支援才行;

8 執行緒池 submit 有兩個方法,方法一可接受 runnable,方法二可接受 callable,但兩個方法底層的邏輯卻是同一套,這是如何適配的?

問題考察點在於 runnable 和 callable 之間是如何轉化的,可以這麼回答;

runnable 和 callable 是通過 futuretask 進行統一的,futuretask 有個屬性是 callable,同時也實現了 runnable 介面,兩者的統一轉化是在 futuretask 的構造器裡實現的,futuretask 的最終目標是把 runnable 和 callable 都轉化成 callable,runnable 轉化成 callable 是通過 runnableadapter 介面卡進行實現的。

執行緒池的 submit 底層的邏輯只認 futuretask,不認 runnable 和 callable 的差異,所以只要都轉化成 futuretask,底層實現都會是同一套;

9 callable 能否丟給 thread 去執行?

可以的,可以新建 callable,並作為 futuretask 的構造器入參,然後把 futuretask 丟給 thread 去執行即可

10 futuretask 有什麼作用(談談對 futuretask 的理解?

組合了 callable,實現了 runnable,把 callable 和 runnnable 串聯了起來,統一了有參任務和無參任務兩種定義方式,方便了使用,實現了 future 的所有方法,對任務有一定的管理功能,比如說拿到任務執行結果,取消任務,打斷任務等

11 聊聊對 futuretask 的 get、cancel 方法的理解?

get 方法主要作用是得到 callable 非同步任務執行的結果,無參 get 會一直等待任務執行完成之後才返回,有參 get 方法可以設定固定的時間,在設定的時間內,如果任務還沒有執行成功,直接返回異常,在實際工作中,建議多多使用 get 有參方法,少用 get 無參方法,防止任務執行過慢時,多數執行緒都在等待,造成執行緒耗盡的問題;

cancel 方法主要用來取消任務,如果任務還沒有執行,是可以取消的,如果任務已經在執行過程中了,你可以選擇不取消,或者直接打斷執行中的任務。

12 thread.yield 方法在工作中有什麼用?

yield 方法表示當前執行緒放棄 cpu,重新參與到 cpu 的競爭中去,再次競爭時,自己有可能得到 cpu 資源,也有可能得不到,這樣做的好處是防止當前執行緒一直霸佔 cpu;

在工作中可能會寫一些 while 自旋的**,如果我們一直 while 自旋,不採取任何手段,我們會發現 cpu 一直被當前 while 迴圈占用,如果能預見 while 自旋時間很長,我們會設定一定的判斷條件,讓當前執行緒陷入阻塞,如果能預見 while 自旋時間很短,我們通常會使用 thread.yield 方法,使當前自旋執行緒讓步,不一直霸佔 cpu,比如這樣:

13  wait()和sleep()的相同點和區別?

wait 是 object 類的方法,sleep 是 thread 類的方法;sleep 不會釋放鎖,沉睡的時候,其它執行緒是無法獲得鎖的,但 wait 會釋放鎖,即最主要的區別sleep 不會釋放鎖,wait 會釋放鎖

14 寫乙個簡單的死鎖 demo

// 共享變數 1

private static final object share1 = new object();

// 共享變數 2

private static final object share2 = new object();

@test

public void testdeadlock() throws interruptedexception catch (interruptedexception e)

synchronized (share2) is run",thread.currentthread().getname());}}

});// 初始化執行緒 2,執行緒 2 需要在鎖定 share2 共享資源的情況下再鎖定 share1

thread thread2 = new thread(() -> catch (interruptedexception e)

synchronized (share1) is run",thread.currentthread().getname());}}

});// 當執行緒 1、2 啟動後,都在等待對方鎖定的資源,但都得不到,造成死鎖

thread1.start();

thread2.start();

thread.sleep(1000000000);

}

GLide 原始碼 面試

glide.with this load url into imageview with load url 1.glide是支援url字串 本地路徑等等載入形式的 2.它提供了asbitmap 和asgif 這兩個方法 它們分別又建立了乙個bitmaptyperequest和giftypereque...

HashMap 原始碼面試

問 先講講hashmap 的資料結構 答 jdk8 中 hashmap 是 陣列 鍊錶 紅黑樹,每個資料單元是乙個 node 結構。jdk 1.7 是 entry 陣列,資料單元是 entry node 結構有 key 字段,有 value 字段,還有 next 字段,還有 hash 字段。next...

面試中strcpy原始碼的判分標準

如果編寫乙個標準strcpy函式的總分值為10,下面給出幾個不同得分的答案 2分 void strcpy char strdest,char strsrc 4分 void strcpy char strdest,const char strsrc 將源字串加const,表明其為輸入引數,加2分 7分...