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

java 多線程面試題

obj 高級 註意 執行 本地線程 java 多線程 也不會 以及 native

0、Java中多線程同步是什麽?

在多線程程序下,同步能控制對共享資源的訪問。如果沒有同步,當一個Java線程在修改一個共享變量時,另外一個線程正在使用或者更新同一個變量,這樣容易導致程序出現錯誤的結果。

1、解釋實現多線程的幾種方法?

Java線程可以實現Runnable接口或者繼承Thread類來實現,當你打算多重繼承時,優先選擇實現Runnable。還可以使用線程池。

2、Thread.start()與Thread.run()有什麽區別?

Thread.start()方法(native)啟動線程,使之進入就緒狀態,當cpu分配時間該線程時,由JVM調度執行run()方法。

3、為什麽需要run()和start()方法,我們可以只用run()方法來完成任務嗎?

我們需要run()&start()這兩個方法是因為JVM創建一個單獨的線程不同於普通方法的調用, 所以這項工作由線程的start方法來完成,start由本地方法實現,需要顯示地被調用,使用這倆個方法的另外一個好處是任何一個對象都可以作為線程運 行,只要實現了Runnable接口,這就避免因繼承了Thread類而造成的Java的多繼承問題。

4、什麽是ThreadLocal類,怎麽使用它?

ThreadLocal是一個線程級別的局部變量,並非“本地線程”。ThreadLocal為每個使用該變量的線程提供了一個獨立的變量副本,每個線程修改副本時不影響其它線程對象的副本(譯者註)。

5、Sleep()、suspend()和wait()之間有什麽區別?

Thread.sleep()使當前線程在指定的時間處於“非運行”(Not Runnable)狀態。線程一直持有對象的監視器。比如一個線程當前在一個同步塊或同步方法中,其它線程不能進入該塊或方法中。如果另一線程調用了 interrupt()方法,它將喚醒那個“睡眠的”線程。

註意:sleep()是一個靜態方法。這意味著只對當前線程有效,一個常見的錯誤是調用t.sleep(),(這裏的t是一個不同於當前線程的線 程)。即便是執行t.sleep(),也是當前線程進入睡眠,而不是t線程。t.suspend()是過時的方法,使用suspend()導致線程進入停 滯狀態,該線程會一直持有對象的監視器,suspend()容易引起死鎖問題。

object.wait()使當前線程出於“不可運行”狀態,和sleep()不同的是wait是object的方法而不是thread。調用 object.wait()時,線程先要獲取這個對象的對象鎖,當前線程必須在鎖對象保持同步,把當前線程添加到等待隊列中,隨後另一線程可以同步同一個 對象鎖來調用object.notify(),這樣將喚醒原來等待中的線程,然後釋放該鎖。基本上wait()/notify()與sleep() /interrupt()類似,只是前者需要獲取對象鎖。

6、在靜態方法上使用同步時會發生什麽事?

同步靜態方法時會獲取該類的“Class”對象,所以當一個線程進入同步的靜態方法中時,線程監視器獲取類本身的對象鎖,其它線程不能進入這個類的任何靜態同步方法。它不像實例方法,因為多個線程可以同時訪問不同實例同步實例方法。

7、當一個同步方法已經執行,線程能夠調用對象上的非同步實例方法嗎?

可以,一個非同步方法總是可以被調用而不會有任何問題。實際上,Java沒有為非同步方法做任何檢查,鎖對象僅 僅在同步方法或者同步代碼塊中檢查。如果一個方法沒有聲明為同步,即使你在使用共享數據Java照樣會調用,而不會做檢查是否安全,所以在這種情況下要特 別小心。一個方法是否聲明為同步取決於臨界區訪問(critial section access),如果方法不訪問臨界區(共享資源或者數據結構)就沒必要聲明為同步的。

8、 在一個對象上兩個線程可以調用兩個不同的同步實例方法嗎?

不能,因為一個對象已經同步了實例方法,線程獲取了對象的對象鎖。所以只有執行完該方法釋放對象鎖後才能執行其 它同步方法。看下面代碼示例非常清晰:Common 類 有synchronizedMethod1()和synchronizedMethod2()方法,MyThread調用這兩個方法。

10、 什麽是死鎖

死鎖就是兩個或兩個以上的線程被無限的阻塞,線程之間相互等待所需資源。這種情況可能發生在當兩個線程嘗試獲取其它資源的鎖,而每個線程又陷入無限等待其它資源鎖的釋放,除非一個用戶進程被終止。

11、現在有T1、T2、T3三個線程,你怎樣保證T2在T1執行完後執行,T3在T2執行完後執行?

使用join()方法

12、在Java中Lock接口比synchronized塊的優勢是什麽?

主要相同點:Lock能完成synchronized所實現的所有功能

主要不同點:Lock有比synchronized更精確的線程語義和更好的性能。synchronized會自動釋放鎖,而Lock一定要求程序員手工釋放,並且必須在finally從句中釋放。

13、用Java寫代碼來解決生產者——消費者問題。

與上面的問題很類似,但這個問題更經典,有些時候面試都會問下面的問題。在Java中怎麽解決生產者——消費者問題,當然有很多解決方法,我已經分享了一種用阻塞隊列實現的方法。有些時候他們甚至會問怎麽實現哲學家進餐問題。

14、什麽是競爭條件?你怎樣發現和解決競爭?

這是一道出現在多線程面試的高級階段的問題。大多數的面試官會問最近你遇到的競爭條件,以及你是怎麽解決的。有些時間他們會寫簡單的代碼,然後讓你檢測出代碼的競爭條件。可以參考我之前發布的關於Java競爭條件的文章。在我看來這是最好的java線程面試問題之一,它可以確切的檢測候選者解決競爭條件的經驗,or writing code which is free of data race or any other race condition。關於這方面最好的書是《Concurrency practices in Java》。

15、為什麽我們調用start()方法時會執行run()方法,為什麽我們不能直接調用run()方法?

這是另一個非常經典的java多線程面試問題。這也是我剛開始寫線程程序時候的困惑。現在這個問題通常在電話面試或者是在初中級Java面試的第一輪被問到。這個問題的回答應該是這樣的,當你調用start()方法時你將創建新的線程,並且執行在run()方法裏的代碼。但是如果你直接調用run()方法,它不會創建新的線程也不會執行調用線程的代碼。

java 多線程面試題