每個(gè)人都曾試圖在平淡的學(xué)習(xí)、工作和生活中寫一篇文章,。寫作是培養(yǎng)人的觀察,、聯(lián)想,、想象,、思維和記憶的重要手段,。那么我們?cè)撊绾螌懸黄^為完美的范文呢,?接下來(lái)小編就給大家介紹一下優(yōu)秀的范文該怎么寫,,我們一起來(lái)看一看吧。
java面試 多線程篇一
很多核心 java 面試題來(lái)源于多線程(multi-threading)和集合框架(collections framework),,理解核心線程概念時(shí),,嫻熟的實(shí)際經(jīng)驗(yàn)是必需的。這篇文章收集了 java 線程方面一些典型的問(wèn)題,,這些問(wèn)題經(jīng)常被高級(jí)工程師所問(wèn)到,。
0、java 中多線程同步是什么?
在多線程程序下,,同步能控制對(duì)共享資源的訪問(wèn),。如果沒(méi)有同步,當(dāng)一個(gè) java 線程在修改一個(gè)共享變量時(shí),,另外一個(gè)線程正在使用或者更新同一個(gè)變量,,這樣容易導(dǎo)致程序出現(xiàn)錯(cuò)誤的結(jié)果。
1,、解釋實(shí)現(xiàn)多線程的幾種方法?
一 java 線程可以實(shí)現(xiàn) runnable 接口或者繼承 thread 類來(lái)實(shí)現(xiàn),,當(dāng)你打算多重繼承時(shí),優(yōu)先選擇實(shí)現(xiàn) runnable,。
2,、 ()與 ()有什么區(qū)別?
()方法(native)啟動(dòng)線程,,使之進(jìn)入就緒狀態(tài),,當(dāng) cpu 分配時(shí)間該線程時(shí),由 jvm 調(diào)度執(zhí)行 run ()方法,。
3,、為什么需要 run ()和 start ()方法,我們可以只用 run ()方法來(lái)完成任務(wù)嗎,?
我們需要 run ()&start ()這兩個(gè)方法是因?yàn)?jvm 創(chuàng)建一個(gè)單獨(dú)的線程不同于普通方法的調(diào)用,,所以這項(xiàng)工作由線程的 start 方法來(lái)完成,start 由本地方法實(shí)現(xiàn),,需要顯示地被調(diào)用,使用這倆個(gè)方法的另外一個(gè)好處是任何一個(gè)對(duì)象都可以作為線程運(yùn)行,,只要實(shí)現(xiàn)了 runnable 接口,,這就避免因繼承了 thread 類而造成的 java 的多繼承問(wèn)題。
4,、什么是 threadlocal 類,,怎么使用它?
threadlocal 是一個(gè)線程級(jí)別的局部變量,,并非“本地線程”,。threadlocal 為每個(gè)使用該變量的線程提供了一個(gè)獨(dú)立的變量副本,每個(gè)線程修改副本時(shí)不影響其它線程對(duì)象的.副本(譯者注),。
下面是線程局部變量(threadlocal variables)的關(guān)鍵點(diǎn):
一個(gè)線程局部變量(threadlocal variables)為每個(gè)線程方便地提供了一個(gè)單獨(dú)的變量,。
threadlocal 實(shí)例通常作為靜態(tài)的私有的(private static)字段出現(xiàn)在一個(gè)類中,這個(gè)類用來(lái)關(guān)聯(lián)一個(gè)線程,。
當(dāng)多個(gè)線程訪問(wèn) threadlocal 實(shí)例時(shí),,每個(gè)線程維護(hù) threadlocal 提供的獨(dú)立的變量副本。
常用的使用可在 dao 模式中見(jiàn)到,當(dāng) dao 類作為一個(gè)單例類時(shí),,數(shù)據(jù)庫(kù)鏈接(connection)被每一個(gè)線程獨(dú)立的維護(hù),,互不影響。(基于線程的單例)
5,、什么時(shí)候拋出 invalidmonitorstateexception 異常,,為什么?
調(diào)用 wait ()/notify ()/notifyall ()中的任何一個(gè)方法時(shí),,如果當(dāng)前線程沒(méi)有獲得該對(duì)象的鎖,,那么就會(huì)拋出 illegalmonitorstateexception 的異常(也就是說(shuō)程序在沒(méi)有執(zhí)行對(duì)象的任何同步塊或者同步方法時(shí),仍然嘗試調(diào)用 wait ()/notify ()/notifyall ()時(shí)),。由于該異常是 runtimeexcpetion 的子類,,所以該異常不一定要捕獲(盡管你可以捕獲只要你愿意).作為 runtimeexception,此類異常不會(huì)在 wait (),notify (),notifyall ()的方法簽名提及,。
6,、sleep ()、suspend ()和 wait ()之間有什么區(qū)別,?
()使當(dāng)前線程在指定的時(shí)間處于“非運(yùn)行”(not runnable)狀態(tài),。線程一直持有對(duì)象的監(jiān)視器。比如一個(gè)線程當(dāng)前在一個(gè)同步塊或同步方法中,,其它線程不能進(jìn)入該塊或方法中,。如果另一線程調(diào)用了 interrupt ()方法,它將喚醒那個(gè)“睡眠的”線程,。
注意:sleep ()是一個(gè)靜態(tài)方法,。這意味著只對(duì)當(dāng)前線程有效, (),,(這里的t是一個(gè)不同于當(dāng)前線程的線程),。 (),也是當(dāng)前線程進(jìn)入睡眠,,而不是t線程,。d ()是過(guò)時(shí)的方法,使用 suspend ()導(dǎo)致線程進(jìn)入停滯狀態(tài),,該線程會(huì)一直持有對(duì)象的監(jiān)視器,,suspend ()容易引起死鎖問(wèn)題。
()使當(dāng)前線程出于“不可運(yùn)行”狀態(tài),,和 sleep ()不同的是 wait 是 object 的方法而不是 thread,。調(diào)用 ()時(shí),線程先要獲取這個(gè)對(duì)象的對(duì)象鎖,,當(dāng)前線程必須在鎖對(duì)象保持同步,,把當(dāng)前線程添加到等待隊(duì)列中,,隨后另一線程可以同步同一個(gè)對(duì)象鎖來(lái)調(diào)用 (),這樣將喚醒原來(lái)等待中的線程,,然后釋放該鎖,。基本上 wait ()/notify ()與 sleep ()/interrupt ()類似,,只是前者需要獲取對(duì)象鎖,。
7、在靜態(tài)方法上使用同步時(shí)會(huì)發(fā)生什么事,?
同步靜態(tài)方法時(shí)會(huì)獲取該類的“class”對(duì)象,,所以當(dāng)一個(gè)線程進(jìn)入同步的靜態(tài)方法中時(shí),線程監(jiān)視器獲取類本身的對(duì)象鎖,,其它線程不能進(jìn)入這個(gè)類的任何靜態(tài)同步方法,。它不像實(shí)例方法,因?yàn)槎鄠€(gè)線程可以同時(shí)訪問(wèn)不同實(shí)例同步實(shí)例方法,。
8,、當(dāng)一個(gè)同步方法已經(jīng)執(zhí)行,線程能夠調(diào)用對(duì)象上的非同步實(shí)例方法嗎,?
可以,,一個(gè)非同步方法總是可以被調(diào)用而不會(huì)有任何問(wèn)題。實(shí)際上,,java 沒(méi)有為非同步方法做任何檢查,,鎖對(duì)象僅僅在同步方法或者同步代碼塊中檢查。如果一個(gè)方法沒(méi)有聲明為同步,,即使你在使用共享數(shù)據(jù) java 照樣會(huì)調(diào)用,,而不會(huì)做檢查是否安全,所以在這種情況下要特別小心,。一個(gè)方法是否聲明為同步取決于臨界區(qū)訪問(wèn)(critial section access),,如果方法不訪問(wèn)臨界區(qū)(共享資源或者數(shù)據(jù)結(jié)構(gòu))就沒(méi)必要聲明為同步的。
下面有一個(gè)示例說(shuō)明:common 類有兩個(gè)方法 synchronizedmethod1()和 method1(),,mythread 類在獨(dú)立的線程中調(diào)用這兩個(gè)方法。
public class common { public synchronized void synchronizedmethod1() { n("synchronizedmethod1 called"); try { (1000); } catch (interruptedexception e) { tacktrace(); } n("synchronizedmethod1 done"); } public void method1() { n("method 1 called"); try { (1000); } catch (interruptedexception e) { tacktrace(); } n("method 1 done"); } }
public class mythread extends thread { private int id = 0; private common common; public mythread(string name, int no, common object) { super(name); common = object; id = no; } public void run() { n("running thread" + e()); try { if (id == 0) { onizedmethod1(); } else { 1(); } } catch (exception e) { tacktrace(); } } public static void main(string[] args) { common c = new common(); mythread t1 = new mythread("mythread-1", 0, c); mythread t2 = new mythread("mythread-2", 1, c); (); (); } }
這里是程序的輸出:
running threadmythread-1
synchronizedmethod1 called
running threadmythread-2
method 1 called
synchronizedmethod1 done
method 1 done
結(jié)果表明即使 synchronizedmethod1()方法執(zhí)行了,,method1()也會(huì)被調(diào)用,。
9、 在一個(gè)對(duì)象上兩個(gè)線程可以調(diào)用兩個(gè)不同的同步實(shí)例方法嗎,?
不能,,因?yàn)橐粋€(gè)對(duì)象已經(jīng)同步了實(shí)例方法,線程獲取了對(duì)象的對(duì)象鎖,。所以只有執(zhí)行完該方法釋放對(duì)象鎖后才能執(zhí)行其它同步方法,。看下面代碼示例非常清晰:common 類有 synchronizedmethod1()和 synchronizedmethod2()方法,mythread 調(diào)用這兩個(gè)方法,。
public class common { public synchronized void synchronizedmethod1() { n("synchronizedmethod1 called"); try { (1000); } catch (interruptedexception e) { tacktrace(); } n("synchronizedmethod1 done"); } public synchronized void synchronizedmethod2() { n("synchronizedmethod2 called"); try { (1000); } catch (interruptedexception e) { tacktrace(); } n("synchronizedmethod2 done"); } }
public class mythread extends thread { private int id = 0; private common common; public mythread(string name, int no, common object) { super(name); common = object; id = no; } public void run() { n("running thread" + e()); try { if (id == 0) { onizedmethod1(); } else { onizedmethod2(); } } catch (exception e) { tacktrace(); } } public static void main(string[] args) { common c = new common(); mythread t1 = new mythread("mythread-1", 0, c); mythread t2 = new mythread("mythread-2", 1, c); (); (); } }
10,、 什么是死鎖
死鎖就是兩個(gè)或兩個(gè)以上的線程被無(wú)限的阻塞,線程之間相互等待所需資源,。這種情況可能發(fā)生在當(dāng)兩個(gè)線程嘗試獲取其它資源的鎖,,而每個(gè)線程又陷入無(wú)限等待其它資源鎖的釋放,除非一個(gè)用戶進(jìn)程被終止,。就 javaapi 而言,,線程死鎖可能發(fā)生在一下情況。
當(dāng)兩個(gè)線程相互調(diào)用 () 當(dāng)兩個(gè)線程使用嵌套的同步塊,,一個(gè)線程占用了另外一個(gè)線程必需的鎖,,互相等待時(shí)被阻塞就有可能出現(xiàn)死鎖。
11,、什么是線程餓死,,什么是活鎖?
線程餓死和活鎖雖然不想是死鎖一樣的常見(jiàn)問(wèn)題,,但是對(duì)于并發(fā)編程的設(shè)計(jì)者來(lái)說(shuō)就像一次邂逅一樣,。
當(dāng)所有線程阻塞,或者由于需要的資源無(wú)效而不能處理,,不存在非阻塞線程使資源可用,。javaapi 中線程活鎖可能發(fā)生在以下情形:
當(dāng)所有線程在程序中執(zhí)行 (0),參數(shù)為 0 的 wait 方法,。程序?qū)l(fā)生活鎖直到在相應(yīng)的對(duì)象上有線程調(diào)用 ()或者 all (),。 當(dāng)所有線程卡在無(wú)限循環(huán)中。
這里的問(wèn)題并不詳盡,,希望對(duì)大家有所幫助,,如果大家有任何疑問(wèn)請(qǐng)給我們留言,小編會(huì)及時(shí)回復(fù)大家的,。在此也非常感謝大家對(duì)的支持,!
s("content_relate");【關(guān)于java程序員面試中的多線程問(wèn)題總結(jié)】相關(guān)文章:
1.
40個(gè)java多線程問(wèn)題總結(jié)
2.關(guān)于java多線程介紹
3.java多線程面試題及回答
4.java多線程介紹
5.java多線程教程
6.舉例講解java中的多線程范文欣賞
7.java多線程的開(kāi)發(fā)技巧
8.java多線程的基本使用