java多線程面試題
一個線程局部變量(ThreadLocal variables)為每個線程方便地提供了一個單獨(dú)的變量。下面就由學(xué)習(xí)啦小編為大家介紹一下java多線程面試題的文章,歡迎閱讀。
java多線程面試題篇1
0.Java 中多線程同步是什么?
在多線程程序下,同步能控制對共享資源的訪問。如果沒有同步,當(dāng)一個 Java 線程在修改一個共享變量時,另外一個線程正在使用或者更新同一個變量,這樣容易導(dǎo)致程序出現(xiàn)錯誤的結(jié)果。
1.解釋實(shí)現(xiàn)多線程的幾種方法?
一 Java 線程可以實(shí)現(xiàn) Runnable 接口或者繼承 Thread 類來實(shí)現(xiàn),當(dāng)你打算多重繼承時,優(yōu)先選擇實(shí)現(xiàn) Runnable。
2.Thread.start ()與 Thread.run ()有什么區(qū)別?
Thread.start ()方法(native)啟動線程,使之進(jìn)入就緒狀態(tài),當(dāng) cpu 分配時間該線程時,由 JVM 調(diào)度執(zhí)行 run ()方法。
3.為什么需要 run ()和 start ()方法,我們可以只用 run ()方法來完成任務(wù)嗎?
我們需要 run ()&start ()這兩個方法是因?yàn)?JVM 創(chuàng)建一個單獨(dú)的線程不同于普通方法的調(diào)用,所以這項(xiàng)工作由線程的 start 方法來完成,start 由本地方法實(shí)現(xiàn),需要顯示地被調(diào)用,使用這倆個方法的另外一個好處是任何一個對象都可以作為線程運(yùn)行,只要實(shí)現(xiàn)了 Runnable 接口,這就避免因繼承了 Thread 類而造成的 Java 的多繼承問題。
java多線程面試題篇2
1.什么是 ThreadLocal 類,怎么使用它?
ThreadLocal 是一個線程級別的局部變量,并非“本地線程”。ThreadLocal 為每個使用該變量的線程提供了一個獨(dú)立的變量副本,每個線程修改副本時不影響其它線程對象的副本(譯者注)。
下面是線程局部變量(ThreadLocal variables)的關(guān)鍵點(diǎn):
一個線程局部變量(ThreadLocal variables)為每個線程方便地提供了一個單獨(dú)的變量。
ThreadLocal 實(shí)例通常作為靜態(tài)的私有的(private static)字段出現(xiàn)在一個類中,這個類用來關(guān)聯(lián)一個線程。
當(dāng)多個線程訪問 ThreadLocal 實(shí)例時,每個線程維護(hù) ThreadLocal 提供的獨(dú)立的變量副本。
常用的使用可在 DAO 模式中見到,當(dāng) DAO 類作為一個單例類時,數(shù)據(jù)庫鏈接(connection)被每一個線程獨(dú)立的維護(hù),互不影響。(基于線程的單例)
ThreadLocal 難于理解,下面這些引用連接有助于你更好的理解它。
《Good article on ThreadLocal on IBM DeveloperWorks 》、《理解 ThreadLocal》、《Managing data : Good example》、《Refer Java API Docs》
2.什么時候拋出 InvalidMonitorStateException 異常,為什么?
調(diào)用 wait ()/notify ()/notifyAll ()中的任何一個方法時,如果當(dāng)前線程沒有獲得該對象的鎖,那么就會拋出 IllegalMonitorStateException 的異常(也就是說程序在沒有執(zhí)行對象的任何同步塊或者同步方法時,仍然嘗試調(diào)用 wait ()/notify ()/notifyAll ()時)。由于該異常是 RuntimeExcpetion 的子類,所以該異常不一定要捕獲(盡管你可以捕獲只要你愿意).作為 RuntimeException,此類異常不會在 wait (),notify (),notifyAll ()的方法簽名提及。
java多線程面試題篇3
1.Sleep ()、suspend ()和 wait ()之間有什么區(qū)別?
Thread.sleep ()使當(dāng)前線程在指定的時間處于“非運(yùn)行”(Not Runnable)狀態(tài)。線程一直持有對象的監(jiān)視器。比如一個線程當(dāng)前在一個同步塊或同步方法中,其它線程不能進(jìn)入該塊或方法中。如果另一線程調(diào)用了 interrupt ()方法,它將喚醒那個“睡眠的”線程。
注意:sleep ()是一個靜態(tài)方法。這意味著只對當(dāng)前線程有效,一個常見的錯誤是調(diào)用t.sleep (),(這里的t是一個不同于當(dāng)前線程的線程)。即便是執(zhí)行t.sleep (),也是當(dāng)前線程進(jìn)入睡眠,而不是t線程。t.suspend ()是過時的方法,使用 suspend ()導(dǎo)致線程進(jìn)入停滯狀態(tài),該線程會一直持有對象的監(jiān)視器,suspend ()容易引起死鎖問題。
object.wait ()使當(dāng)前線程出于“不可運(yùn)行”狀態(tài),和 sleep ()不同的是 wait 是 object 的方法而不是 thread。調(diào)用 object.wait ()時,線程先要獲取這個對象的對象鎖,當(dāng)前線程必須在鎖對象保持同步,把當(dāng)前線程添加到等待隊(duì)列中,隨后另一線程可以同步同一個對象鎖來調(diào)用 object.notify (),這樣將喚醒原來等待中的線程,然后釋放該鎖?;旧?wait ()/notify ()與 sleep ()/interrupt ()類似,只是前者需要獲取對象鎖。
2.在靜態(tài)方法上使用同步時會發(fā)生什么事?
同步靜態(tài)方法時會獲取該類的“Class”對象,所以當(dāng)一個線程進(jìn)入同步的靜態(tài)方法中時,線程監(jiān)視器獲取類本身的對象鎖,其它線程不能進(jìn)入這個類的任何靜態(tài)同步方法。它不像實(shí)例方法,因?yàn)槎鄠€線程可以同時訪問不同實(shí)例同步實(shí)例方法。
3.當(dāng)一個同步方法已經(jīng)執(zhí)行,線程能夠調(diào)用對象上的非同步實(shí)例方法嗎?
可以,一個非同步方法總是可以被調(diào)用而不會有任何問題。實(shí)際上,Java 沒有為非同步方法做任何檢查,鎖對象僅僅在同步方法或者同步代碼塊中檢查。如果一個方法沒有聲明為同步,即使你在使用共享數(shù)據(jù) Java 照樣會調(diào)用,而不會做檢查是否安全,所以在這種情況下要特別小心。一個方法是否聲明為同步取決于臨界區(qū)訪問(critial section access),如果方法不訪問臨界區(qū)(共享資源或者數(shù)據(jù)結(jié)構(gòu))就沒必要聲明為同步的。