1. 程式人生 > >精選多執行緒面試題目和答案,對多執行緒理解不是很到位的快來看了~

精選多執行緒面試題目和答案,對多執行緒理解不是很到位的快來看了~

多執行緒,相信對於很多小白來說是噩夢一般的東西吧,別怕,接下來我們就來把多執行緒的一些面試題一一解讀,希望讀完這篇文章之後,能夠對多執行緒有一個更深入的瞭解。

1. 多執行緒使用的優缺點?

優點:
(1)多執行緒技術使程式的響應速度更快
(2)當前沒有進行處理的任務可以將處理器時間讓給其它任務
(3)佔用大量處理時間的任務可以定期將處理器時間讓給其它任務
(4)可以隨時停止任務
(5)可以分別設定各個任務的優先順序以及優化效能

缺點:
(1)等候使用共享資源時造成程式的執行速度變慢
(2)對執行緒進行管理要求額外的cpu開銷
(3)可能出現執行緒死鎖情況。即較長時間的等待或資源競爭以及死鎖等症狀。

2. start()方法和run()方法簡介和區別?

start()方法:
(1)用start方法來啟動執行緒,真正實現了多執行緒執行,這時無需等待run方法體程式碼執行完畢而直接繼續執行下面的程式碼。
(2)通過呼叫Thread類的start()方法來啟動一個執行緒,這時此執行緒處於就緒(可執行)狀態,並沒有執行,一旦得到CPU時間片,就開始執行run()方法。

run()方法:
run()方法只是類的一個普通方法而已,如果直接呼叫Run方法,程式中依然只有主執行緒這一個執行緒,其程式執行路徑還是隻有一條。

總結:
(1)呼叫start方法方可啟動執行緒,
(2)而run方法只是thread的一個普通方法呼叫,還是在主執行緒裡執行。
(3)把需要並行處理的程式碼放在run()方法中,start()方法啟動執行緒將自動呼叫run()方法,這是由jvm的記憶體機制規定的。
(4)並且run()方法必須是public訪問許可權,返回值型別為void.。

3. Runnable介面和Callable介面的相同點和不同點?

4. volatile關鍵字的作用是什麼?

(1)多執行緒使用volatile關鍵字修飾的變數,保證了其在多執行緒之間的可見性,即每次讀取到volatile變數,一定是最新的資料
(2)Java程式碼執行中,為了獲取更好的效能JVM可能會對指令進行重排序,多執行緒下可能會出現一些意想不到的問題。使用volatile則會對禁止語義重排序,當然這也一定程度上降低了程式碼執行效率

5. CyclicBarrier和CountDownLatch的區別是什麼?

6. volatile和synchronized對比?

(1)volatile本質是在告訴jvm當前變數在暫存器中的值是不確定的,需要從主存中讀取,synchronized則是鎖定當前變數,只有當前執行緒可以訪問該變數,其他執行緒被阻塞住.
(2)volatile僅能使用在變數級別,synchronized則可以使用在變數,方法.
(3)volatile僅能實現變數的修改可見性,而synchronized則可以保證變數的修改可見性和原子性.
(4)volatile不會造成執行緒的阻塞,而synchronized可能會造成執行緒的阻塞.

7. 怎麼喚醒一個阻塞的執行緒?

如果執行緒是因為呼叫了wait()、sleep()或者join()方法而導致的阻塞,可以中斷執行緒,並且通過丟擲InterruptedException來喚醒它;如果執行緒遇到了IO阻塞,無能為力,因為IO是作業系統實現的,Java程式碼並沒有辦法直接接觸到作業系統。

8. Java中如何獲取到執行緒dump檔案?

dump檔案的作用:
死迴圈、死鎖、阻塞、頁面開啟慢等問題,打執行緒dump是最好的解決問題的途徑。因此,執行緒dump也就是執行緒堆疊。

獲取到執行緒堆疊dump檔案內容分兩步:
(1)第一步:獲取到執行緒的pid,Linux環境下可以使用ps -ef | grep java
(2)第二步:列印執行緒堆疊,可以通過使用jstack pid命令

9. sleep方法和wait方法的相同點和不同點?

相同點:
二者都可以讓執行緒處於凍結狀態。

不同點:
(1)首先應該明確sleep方法是Thread類中定義的方法,而wait方法是Object類中定義的方法。
(2)sleep方法必須人為地為其指定時間。wait方法既可以指定時間,也可以不指定時間。
(3)sleep方法時間到,執行緒處於臨時阻塞狀態或者執行狀態。wait方法如果沒有被設定時間,就必須要通過notify或者notifyAll來喚醒。
(4)sleep方法不一定非要定義在同步中。wait方法必須定義在同步中。
(5)當二者都定義在同步中時,執行緒執行到sleep,不會釋放鎖。執行緒執行到wait,會釋放鎖。

10. 生產者和消費者模型的作用是什麼?

(1)通過平衡生產者的生產能力和消費者的消費能力來提升整個系統的執行效率,這是生產者消費者模型最重要的作用
(2)解耦,這是生產者消費者模型附帶的作用,解耦意味著生產者和消費者之間的聯絡少,聯絡越少越可以獨自發展而不需要收到相互的制約

11. ThreadLocal的作用是什麼?

(1)ThreadLocal用來解決多執行緒程式的併發問題
(2)ThreadLocal並不是一個Thread,而是Thread的區域性變數,當使用ThreadLocal維護變數時,ThreadLocal為每個使用該變數的執行緒提供獨立的變數副本,所以每個執行緒都可以獨立地改變自己的副本,而不會影響其它執行緒所對應的副本.
(3)從執行緒的角度看,目標變數就象是執行緒的本地變數,這也是類名中“Local”所要表達的意思。
(4)執行緒區域性變數並不是Java的新發明,Java沒有提供在語言級支援(語法上),而是變相地通過ThreadLocal的類提供支援.

12. wait方法和notify/notifyAll方法在放棄物件監視器時有什麼區別?

wait()方法立即釋放物件監視器;

notify()/notifyAll()方法則會等待執行緒剩餘程式碼執行完畢才會放棄物件監視器。

13. Lock和synchronized對比

(1)Lock是一個介面,而synchronized是Java中的關鍵字,synchronized是內建的語言實現;
(2)synchronized在發生異常時,會自動釋放執行緒佔有的鎖,因此不會導致死鎖現象發生;而Lock在發生異常時,如果沒有主動通過unLock()去釋放鎖,則很可能造成死鎖現象,因此使用Lock時需要在finally塊中釋放鎖;
(3)Lock可以讓等待鎖的執行緒響應中斷,而synchronized卻不行,使用synchronized時,等待的執行緒會一直等待下去,不能夠響應中斷;
(4)通過Lock可以知道有沒有成功獲取鎖,而synchronized卻無法辦到。
(5)Lock可以提高多個執行緒進行讀操作的效率。
(6)在JDK1.5中,synchronized是效能低效的。因為這是一個重量級操作,它對效能最大的影響是阻塞式的實現,掛起執行緒和恢復執行緒的操作都需要轉入核心態中完成,這些操作給系統的併發性帶來了很大的壓力。相比之下使用Java提供的Lock物件,效能更高一些。但是,JDK1.6,發生了變化,對synchronize加入了很多優化措施,有自適應自旋,鎖消除,鎖粗化,輕量級鎖,偏向鎖等等。導致在JDK1.6上synchronize的效能並不比Lock差。因此。提倡優先考慮使用synchronized來進行同步。

14、ConcurrentHashMap的併發度是什麼?

ConcurrentHashMap的併發度就是segment的大小,預設為16,這意味著最多同時可以有16條執行緒操作ConcurrentHashMap,這也是ConcurrentHashMap對Hashtable的最大優勢,任何情況下,Hashtable能同時有兩條執行緒獲取Hashtable中的資料。

15、ReadWriteLock是什麼?

ReadWriteLock是一個讀寫鎖介面,ReentrantReadWriteLock是ReadWriteLock介面的一個具體實現,實現了讀寫的分離,讀鎖是共享的,寫鎖是獨佔的,讀和讀之間不會互斥,讀和寫、寫和讀、寫和寫之間才會互斥,提升了讀寫的效能。

16、FutureTask是什麼?

FutureTask表示一個非同步運算的任務。FutureTask裡面可以傳入一個Callable的具體實現類,可以對這個非同步運算的任務的結果進行等待獲取、判斷是否已經完成、取消任務等操作。由於FutureTask也是Runnable介面的實現類,所以FutureTask也可以放入執行緒池中。

17、Java中用到的執行緒排程演算法是什麼?

搶佔式。一個執行緒用完CPU之後,作業系統會根據執行緒優先順序、執行緒飢餓情況等資料算出一個總的優先順序並分配下一個時間片給某個執行緒執行。

18、單例模式的執行緒安全性?

單例模式的執行緒安全意味著:某個類的例項在多執行緒環境下只會被建立一次出來。單例模式有很多種的寫法,具體分析如下:

(1)餓漢式單例模式的寫法:執行緒安全
(2)懶漢式單例模式的寫法:非執行緒安全
(3)雙檢鎖單例模式的寫法:執行緒安全

19、什麼是樂觀鎖和悲觀鎖?

(1)樂觀鎖:對於併發間操作產生的執行緒安全問題持樂觀狀態,樂觀鎖認為競爭不總是會發生,因此它不需要持有鎖,將比較-設定這兩個動作作為一個原子操作嘗試去修改記憶體中的變數,如果失敗則表示發生衝突,那麼就應該有相應的重試邏輯。
(2)悲觀鎖:對於併發間操作產生的執行緒安全問題持悲觀狀態,悲觀鎖認為競爭總是會發生,因此每次對某資源進行操作時,都會持有一個獨佔的鎖,就像synchronized,直接對操作資源上了鎖。

20. Java編寫一個會導致死鎖的程式

死鎖現象描述:
執行緒A和執行緒B相互等待對方持有的鎖導致程式無限死迴圈下去。

死鎖的實現步驟:
(1)兩個執行緒裡面分別持有兩個Object物件:lock1和lock2。這兩個lock作為同步程式碼塊的鎖;
(2)執行緒1的run()方法中同步程式碼塊先獲取lock1的物件鎖,Thread.sleep(xxx),時間不需要太多,100毫秒差不多了,然後接著獲取lock2的物件鎖。這麼做主要是為了防止執行緒1啟動一下子就連續獲得了lock1和lock2兩個物件的物件鎖。
(3)執行緒2的run)(方法中同步程式碼塊先獲取lock2的物件鎖,接著獲取lock1的物件鎖,當然這時lock1的物件鎖已經被執行緒1鎖持有,執行緒2肯定是要等待執行緒1釋放lock1的物件鎖的。這樣,執行緒1″睡覺”睡完,執行緒2已經獲取了lock2的物件鎖了,執行緒1此時嘗試獲取lock2的物件鎖,便被阻塞,此時一個死鎖就形成了。

看完之後,不知道大家有沒有更加了解多執行緒呢?如果有正在學java的程式設計師,可來我們的java技術學習扣qun哦:59,789,1510裡面免費送java的視訊系統教程噢!