1. 程式人生 > >多線程面試題

多線程面試題

無需 -- 優點 多核 需要 vol 安全問題 使用 線程處理

什麽是多線程?

多線程(英語:multithreading),是指從軟件或者硬件上實現多個線程並發執行的技術。具有多線程能力的計算機因有硬件支持而能夠在同一時間執行多於一個線程,進而提升整體處理性能。具有這種能力的系統包括對稱多處理機、多核心處理器以及芯片級多處理(Chip-level multithreading)或同時多線程(Simultaneous multithreading)處理器。在一個程序中,這些獨立運行的程序片段叫作“線程”(Thread),利用它編程的概念就叫作“多線程處理(Multithreading)”。具有多線程能力的計算機因有硬件支持而能夠在同一時間執行多於一個線程,進而提升整體處理性能。

線程和進程有什麽區別?

進程是指一種“自包容”的運行程序,有自己的地址空間;線程是進程內部單一的一個順序控制流 進程:每個進程都有獨立的代碼和數據空間(進程上下文),進程間的切換會有較大的開銷,一個進程包含1--n個線程。(進程是資源分配的最小單位) 線程:同一類線程共享代碼和數據空間,每個線程有獨立的運行棧和程序計數器(PC),線程切換開銷小。(線程是cpu調度的最小單位 線程和進程一樣分為五個階段:創建、就緒、運行、阻塞、終止。 線程的運行中需要使用計算機的內存資源和CPU。

如何在Java中使用新線程?

java開啟新線程有三種方法:

方法1:繼承Thread類;

方法2:實現Runnable接口;

方法3:直接在函數體使用(匿名內部類);

start()和run()有什麽區別?

start:用start方法來啟動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。通過調用Thread類的start()方法來啟動一個線程,這時此線程處於就緒(可運行)狀態,並沒有運行,一旦得到cpu時間片,就開始執行run()方法,這裏方法 run()稱為線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程隨即終止。
run:run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是只有一條,還是要順序執行,還是要等待run方法體執行完畢後才可繼續執行下面的代碼,這樣就沒有達到寫線程的目的。總結:調用start方法方可啟動線程,而run方法只是thread的一個普通方法調用,還是在主線程裏執行。這兩個方法應該都比較熟悉,把需要並行處理的代碼放在run()方法中,start()方法啟動線程將自動調用 run()方法,這是由jvm的內存機制規定的。並且run()方法必須是public訪問權限,返回值類型為void.。

總結:調用start方法方可啟動線程並允許run()方法,而run方法只是thread的一個普通方法調用,還是在主線程裏執行。

Thread.join方法有什麽用?

簡單來說就是,你在家看電視,突然有人敲門叫你交水電費,你必須先交完費用才能繼續看電視。也就是說,你必須等待那個插入的線程完成才能繼續。

假如新建T1,T2,T3三個線程,如何保證它們按順序執行?

可以在他們開啟state()之後join(),也可以使用鎖lock()或者synchronized

volatile變了是做什麽的?

a.volatile關鍵字為域變量的訪問提供了一種免鎖機制;
b.使用volatile修飾域相當於告訴虛擬機該域可能會被其他線程更新;
c.因此每次使用該域就要重新計算,而不是使用寄存器中的值;
d.volatile不會提供任何原子操作,它也不能用來修飾final類型的變量;

如果一個線程中發生了異常會怎麽樣?

① 如果該異常被捕獲或拋出,則程序繼續運行。
② 如果異常沒有被捕獲該線程將會停止執行。
Thread.UncaughtExceptionHandler是用於處理未捕獲異常造成線程突然中斷情況的一個內嵌接口。當一個未捕獲異常將造成線程中斷的時候JVM會使用Thread.getUncaughtExceptionHandler()來查詢線程的UncaughtExceptionHandler,並將線程和異常作為參數傳遞給handler的uncaughtException()方法進行處理。

什麽是ThreadLocal變量?

ThreadLocal用於保存某個線程共享變量:對於同一個static ThreadLocal,不同線程只能從中get,set,remove自己的變量,而不會影響其他線程的變量。
1、ThreadLocal.get: 獲取ThreadLocal中當前線程共享變量的值。
2、ThreadLocal.set: 設置ThreadLocal中當前線程共享變量的值。
3、ThreadLocal.remove: 移除ThreadLocal中當前線程共享變量的值。
4、ThreadLocal.initialValue: ThreadLocal沒有被當前線程賦值時或當前線程剛調用remove方法後調用get方法,返回此方法值。

什麽是線程池,為什麽要使用?

將線程添加到一個隊列中,下次創建時查詢池中是否存在,線程數量不能超過最大數。超過最大值的線程可以排隊,但他們要等到其他線程完成後才啟動。
優點:
1.創建/銷毀線程伴隨著系統開銷,過於頻繁的創建/銷毀線程,會很大程度上影響處理效率,減少資源消耗。
2.線程並發數量過多,搶占系統資源從而導致阻塞,處理線程安全問題。
3.對線程進行一些簡單的管理,如:延時執行、定時循環執行的策略。

Thread.sleep 和 wait 方法有什麽不同?

sleep 是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時後會自動恢復,調用sleep 不會釋放對象鎖。由於沒有釋放對象鎖,所以不能調用裏面的同步方法。
sleep()使當前線程進入停滯狀態(阻塞當前線程),讓出CUP的使用、目的是不讓當前線程獨自霸占該進程所獲的CPU資源,以留一定時間給其他線程執行的機會;
sleep()是Thread類的Static(靜態)的方法;因此他不能改變對象的機鎖,所以當在一個Synchronized塊中調用Sleep()方法是,線程雖然休眠了,但是對象的機鎖並木有被釋放,其他線程無法訪問這個對象(即使睡著也持有對象鎖)。

在sleep()休眠時間期滿後,該線程不一定會立即執行,這是因為其它線程可能正在運行而且沒有被調度為放棄執行,除非此線程具有更高的優先級。
wait()方法是Object類裏的方法;當一個線程執行到wait()方法時,它就進入到一個和該對象相關的等待池中,同時失去(釋放)了對象的機鎖(暫時失去機鎖,wait(long timeout)超時時間到後還需要返還對象鎖);可以調用裏面的同步方法,其他線程可以訪問;
wait()使用notify或者notifyAlll或者指定睡眠時間來喚醒當前等待池中的線程。
wiat()必須放在synchronized block中,否則會在program runtime時扔出”java.lang.IllegalMonitorStateException“異常。
總結:sleep與wait不同之處:sleep來自Thread,wait來自Object,sleep不會釋放對象鎖,wait會釋放對象鎖,sleep不用再synchronized中,wait必須要在synchronized中否則會拋出異常。

synchronized 關鍵詞是做什麽的?

預防線程安全問題,同一時間只能有一個線程訪問標有synchronized關鍵字的方法,變量,類。

多線程面試題