Java程序員筆試必備--Java多線程

電子書下載地址: http://wiki.jikexueyuan.com/project/java-interview-bible/

1. 下面哪些是Thread類的方法?

A start() B run() C exit() D getPriority()

答案:ABD

解析:看 Java API docs吧:http://docs.oracle.com/javase/7/docs/api/炫七, exit() 是 System 類的方法,如System.exit(0)筹吐。

2. 下面程序的運行結(jié)果?

   public static void main(String args[]) {
        Thread t = new Thread() {
            public void run() {
                pong();
            }
        };
        t.run();
        System.out.print("ping");
    }
    static void pong() {
        System.out.print("pong");
    }

A. pingpong
B. pongping
C. pingpong和pongping都有可能
D. 都不輸出

答案:B

解析:這里考的是 Thread 類中 start() 和 run() 方法的區(qū)別了盾碗。start() 用來啟動一個線程鸳粉,當調(diào)用 start 方法后富纸,系統(tǒng)才會開啟一個新的線程审姓,進而調(diào)用 run() 方法來執(zhí)行任務珍特,而單獨的調(diào)用run() 就跟調(diào)用普通方法是一樣的,已經(jīng)失去線程的特性了魔吐。因此在啟動一個線程的時候一定要使用 start() 而不是 run()扎筒。

3. 進程和線程的區(qū)別是什么?

進程是執(zhí)行著的應用程序酬姆,而線程是進程內(nèi)部的一個執(zhí)行序列嗜桌。一個進程可以有多個線程。線程又叫做輕量級進程辞色。

4. 創(chuàng)建線程有幾種不同的方式骨宠?你喜歡哪一種?為什么?

有三種方式可以用來創(chuàng)建線程:

  • 繼承 Thread 類
  • 實現(xiàn) Runnable 接口
  • 應用程序可以使用 Executor 框架來創(chuàng)建線程池

實現(xiàn) Runnable 接口這種方式更受歡迎层亿,因為這不需要繼承 Thread 類桦卒。在應用設計中已經(jīng)繼承了別的對象的情況下,這需要多繼承(而 Java 不支持多繼承)匿又,只能實現(xiàn)接口方灾。同時,線程池也是非常高效的碌更,很容易實現(xiàn)和使用迎吵。

5. 概括的解釋下線程的幾種可用狀態(tài)。

線程在執(zhí)行過程中针贬,可以處于下面幾種狀態(tài):

  • 就緒(Runnable):線程準備運行击费,不一定立馬就能開始執(zhí)行。
  • 運行中(Running):進程正在執(zhí)行線程的代碼桦他。
  • 等待中(Waiting):線程處于阻塞的狀態(tài)蔫巩,等待外部的處理結(jié)束。
  • 睡眠中(Sleeping):線程被強制睡眠快压。
  • I/O阻塞(Blocked on I/O):等待I/O操作完成圆仔。
    同步阻塞(Blocked on Synchronization):等待獲取鎖。
  • 死亡(Dead):線程完成了執(zhí)行蔫劣。

6. 同步方法和同步代碼塊的區(qū)別是什么坪郭?

在 Java 語言中,每一個對象有一把鎖脉幢。線程可以使用 synchronized 關(guān)鍵字來獲取對象上的鎖歪沃。 synchronized 關(guān)鍵字可應用在方法級別(粗粒度鎖)或者是代碼塊級別(細粒度鎖)。

7. 在監(jiān)視器(Monitor)內(nèi)部嫌松,是如何做線程同步的沪曙?程序應該做哪種級別的同步?

監(jiān)視器和鎖在 Java 虛擬機中是一塊使用的萎羔。監(jiān)視器監(jiān)視一塊同步代碼塊液走,確保一次只有一個線程執(zhí)行同步代碼塊。每一個監(jiān)視器都和一個對象引用相關(guān)聯(lián)贾陷。線程在獲取鎖之前不允許執(zhí)行同步代碼缘眶。

8. 什么是死鎖(deadlock)?

兩個進程都在等待對方執(zhí)行完畢才能繼續(xù)往下執(zhí)行的時候就發(fā)生了死鎖髓废。結(jié)果就是兩個進程都陷入了無限的等待中巷懈。

9. 如何確保 N 個線程可以訪問 N 個資源同時又不導致死鎖?

使用多線程的時候瓦哎,一種非常簡單的避免死鎖的方式就是:指定獲取鎖的順序砸喻,并強制線程按照指定的順序獲取鎖柔逼。因此,如果所有的線程都是以同樣的順序加鎖和釋放鎖割岛,就不會出現(xiàn)死鎖了

10. sleep() 和 wait() 有什么區(qū)別?

答:sleep()方法是線程類(Thread)的靜態(tài)方法愉适,導致此線程暫停執(zhí)行指定時間,將執(zhí)行機會給其他線程癣漆,但是監(jiān)控狀態(tài)依然保持维咸,到時后會自動恢復(線程回到就緒(ready)狀態(tài)),因為調(diào)用 sleep 不會釋放對象鎖惠爽。wait() 是 Object 類的方法癌蓖,對此對象調(diào)用 wait()方法導致本線程放棄對象鎖(線程暫停執(zhí)行),進入等待此對象的等待鎖定池婚肆,只有針對此對象發(fā)出 notify 方法(或 notifyAll)后本線程才進入對象鎖定池準備獲得對象鎖進入就緒狀態(tài)租副。

補充:這里似乎漏掉了一個作為先決條件的問題,就是什么是進程较性,什么是線程用僧?為什么需要多線程編程?答案如下所示:

進程是具有一定獨立功能的程序關(guān)于某個數(shù)據(jù)集合上的一次運行活動赞咙,是操作系統(tǒng)進行資源分配和調(diào)度的一個獨立單位责循;線程是進程的一個實體,是 CPU 調(diào)度和分派的基本單位攀操,是比進程更小的能獨立運行的基本單位院仿。線程的劃分尺度小于進程,這使得多線程程序的并發(fā)性高速和;進程在執(zhí)行時通常擁有獨立的內(nèi)存單元歹垫,而線程之間可以共享內(nèi)存。使用多線程的編程通常能夠帶來更好的性能和用戶體驗健芭,但是多線程的程序?qū)τ谄渌绦蚴遣挥押玫南卦浚驗樗加昧烁嗟?CPU 資源秀姐。

11. sleep() 和 yield() 有什么區(qū)別?

答:

① sleep() 方法給其他線程運行機會時不考慮線程的優(yōu)先級慈迈,因此會給低優(yōu)先級的線程以運行的機會;yield() 方法只會給相同優(yōu)先級或更高優(yōu)先級的線程以運行的機會省有;

② 線程執(zhí)行 sleep() 方法后轉(zhuǎn)入阻塞(blocked)狀態(tài)痒留,而執(zhí)行 yield() 方法后轉(zhuǎn)入就緒(ready)狀態(tài);

③ sleep() 方法聲明拋出InterruptedException蠢沿,而 yield() 方法沒有聲明任何異常伸头;

④ sleep() 方法比 yield() 方法(跟操作系統(tǒng)相關(guān))具有更好的可移植性。

12. 當一個線程進入一個對象的 synchronized 方法 A 之后舷蟀,其它線程是否可進入此對象的 synchronized 方法恤磷?

答:不能面哼。其它線程只能訪問該對象的非同步方法,同步方法則不能進入扫步。

13. 請說出與線程同步相關(guān)的方法魔策。

答:

  • wait():使一個線程處于等待(阻塞)狀態(tài),并且釋放所持有的對象的鎖河胎;
  • sleep():使一個正在運行的線程處于睡眠狀態(tài)闯袒,是一個靜態(tài)方法,調(diào)用此方法要捕捉InterruptedException 異常游岳;
  • notify():喚醒一個處于等待狀態(tài)的線程政敢,當然在調(diào)用此方法的時候,并不能確切的喚醒某一個等待狀態(tài)的線程胚迫,而是由JVM確定喚醒哪個線程喷户,而且與優(yōu)先級無關(guān);
  • notityAll():喚醒所有處入等待狀態(tài)的線程访锻,注意并不是給所有喚醒線程一個對象的鎖摩骨,而是讓它們競爭;

JDK 1.5 通過 Lock 接口提供了顯式(explicit)的鎖機制朗若,增強了靈活性以及對線程的協(xié)調(diào)恼五。Lock 接口中定義了加鎖(lock())和解鎖(unlock())的方法,同時還提供了 newCondition() 方法來產(chǎn)生用于線程之間通信的 Condition 對象哭懈;

JDK 1.5 還提供了信號量(semaphore)機制灾馒,信號量可以用來限制對某個共享資源進行訪問的線程的數(shù)量。在對資源進行訪問之前遣总,線程必須得到信號量的許可(調(diào)用Semaphore對象的acquire()方法)睬罗;在完成對資源的訪問后,線程必須向信號量歸還許可(調(diào)用 Semaphore 對象的 release() 方法)旭斥。

14. synchronized 關(guān)鍵字的用法容达?

答:synchronized 關(guān)鍵字可以將對象或者方法標記為同步,以實現(xiàn)對對象和方法的互斥訪問垂券,可以用synchronized(對象) { … }定義同步代碼塊花盐,或者在聲明方法時將 synchronized 作為方法的修飾符。在第60題的例子中已經(jīng)展示了 synchronized 關(guān)鍵字的用法菇爪。

15. 舉例說明同步和異步算芯。

答:如果系統(tǒng)中存在臨界資源(資源數(shù)量少于競爭資源的線程數(shù)量的資源),例如正在寫的數(shù)據(jù)以后可能被另一個線程讀到凳宙,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個線程寫過了熙揍,那么這些數(shù)據(jù)就必須進行同步存取(數(shù)據(jù)庫操作中的悲觀鎖就是最好的例子)氏涩。當應用程序在對象上調(diào)用了一個需要花費很長時間來執(zhí)行的方法届囚,并且不希望讓程序等待方法的返回時有梆,就應該使用異步編程,在很多情況下采用異步途徑往往更有效率意系。事實上淳梦,所謂的同步就是指阻塞式操作,而異步就是非阻塞式操作昔字。

16. 啟動一個線程是用 run() 還是 start() 方法?

答:啟動一個線程是調(diào)用 start() 方法爆袍,使線程所代表的虛擬處理機處于可運行狀態(tài),這意味著它可以由JVM 調(diào)度并執(zhí)行作郭,這并不意味著線程就會立即運行陨囊。run()方法是線程啟動后要進行回調(diào)(callback)的方法。

17. 什么是線程池(thread pool)夹攒?

答:在面向?qū)ο缶幊讨兄┐祝瑒?chuàng)建和銷毀對象是很費時間的,因為創(chuàng)建一個對象要獲取內(nèi)存資源或者其它更多資源咏尝。在 Java 中更是如此压语,虛擬機將試圖跟蹤每一個對象,以便能夠在對象銷毀后進行垃圾回收编检。所以提高服務程序效率的一個手段就是盡可能減少創(chuàng)建和銷毀對象的次數(shù)胎食,特別是一些很耗資源的對象創(chuàng)建和銷毀,這就是"池化資源"技術(shù)產(chǎn)生的原因允懂。線程池顧名思義就是事先創(chuàng)建若干個可執(zhí)行的線程放入一個池(容器)中厕怜,需要的時候從池中獲取線程不用自行創(chuàng)建,使用完畢不需要銷毀線程而是放回池中蕾总,從而減少創(chuàng)建和銷毀線程對象的開銷粥航。

18. 線程的基本狀態(tài)以及狀態(tài)之間的關(guān)系?

答:

Paste_Image.png

除去起始(new)狀態(tài)和結(jié)束(finished)狀態(tài)生百,線程有三種狀態(tài)递雀,分別是:就緒(ready)、運行(running)和阻塞(blocked)蚀浆。其中就緒狀態(tài)代表線程具備了運行的所有條件缀程,只等待 CPU 調(diào)度(萬事俱備,只欠東風)蜡坊;處于運行狀態(tài)的線程可能因為 CPU 調(diào)度(時間片用完了)的原因回到就緒狀態(tài)杠输,也有可能因為調(diào)用了線程的 yield 方法回到就緒狀態(tài),此時線程不會釋放它占有的資源的鎖秕衙,坐等 CPU 以繼續(xù)執(zhí)行;運行狀態(tài)的線程可能因為 I/O 中斷僵刮、線程休眠据忘、調(diào)用了對象的 wait 方法而進入阻塞狀態(tài)(有的地方也稱之為等待狀態(tài))鹦牛;而進入阻塞狀態(tài)的線程會因為休眠結(jié)束、調(diào)用了對象的 notify 方法或 notifyAll 方法或其他線程執(zhí)行結(jié)束而進入就緒狀態(tài)勇吊。注意:調(diào)用 wait 方法會讓線程進入等待池中等待被喚醒曼追, notify 方法或 notifyAll 方法會讓等待鎖中的線程從等待池進入等鎖池,在沒有得到對象的鎖之前汉规,線程仍然無法獲得 CPU 的調(diào)度和執(zhí)行礼殊。

19. 死鎖的必要條件?怎么克服针史?

答:產(chǎn)生死鎖的四個必要條件:

互斥條件:一個資源每次只能被一個進程使用晶伦。

請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放啄枕。

不剝奪條件:進程已獲得的資源婚陪,在末使用完之前,不能強行剝奪频祝。

循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系泌参。

這四個條件是死鎖的必要條件,只要系統(tǒng)發(fā)生死鎖常空,這些條件必然成立沽一,而只要上述條件之一不滿足,就不會發(fā)生死鎖漓糙。

死鎖的解決方法:

a 撤消陷于死鎖的全部進程锯玛;
b 逐個撤消陷于死鎖的進程,直到死鎖不存在兼蜈;
c 從陷于死鎖的進程中逐個強迫放棄所占用的資源攘残,直至死鎖消失。
d 從另外一些進程那里強行剝奪足夠數(shù)量的資源分配給死鎖進程为狸,以解除死鎖狀態(tài)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末歼郭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子辐棒,更是在濱河造成了極大的恐慌病曾,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漾根,死亡現(xiàn)場離奇詭異泰涂,居然都是意外死亡,警方通過查閱死者的電腦和手機辐怕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門逼蒙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人寄疏,你說我怎么就攤上這事是牢〗┚” “怎么了?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵驳棱,是天一觀的道長批什。 經(jīng)常有香客問我,道長社搅,這世上最難降的妖魔是什么驻债? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮形葬,結(jié)果婚禮上合呐,老公的妹妹穿的比我還像新娘。我一直安慰自己荷并,他們只是感情好合砂,可當我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著源织,像睡著了一般翩伪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谈息,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天缘屹,我揣著相機與錄音,去河邊找鬼侠仇。 笑死轻姿,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的逻炊。 我是一名探鬼主播互亮,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼余素!你這毒婦竟也來了豹休?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤桨吊,失蹤者是張志新(化名)和其女友劉穎威根,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體视乐,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡洛搀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了佑淀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片留美。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出独榴,到底是詐尸還是另有隱情僧叉,我是刑警寧澤奕枝,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布棺榔,位于F島的核電站,受9級特大地震影響隘道,放射性物質(zhì)發(fā)生泄漏症歇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一谭梗、第九天 我趴在偏房一處隱蔽的房頂上張望忘晤。 院中可真熱鬧,春花似錦激捏、人聲如沸设塔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闰蛔。三九已至,卻和暖如春图柏,著一層夾襖步出監(jiān)牢的瞬間序六,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工蚤吹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留例诀,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓裁着,卻偏偏與公主長得像繁涂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子二驰,可洞房花燭夜當晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Java多線程學習 [-] 一擴展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,964評論 1 18
  • 本文主要講了java中多線程的使用方法扔罪、線程同步、線程數(shù)據(jù)傳遞诸蚕、線程狀態(tài)及相應的一些線程函數(shù)用法步势、概述等。 首先講...
    李欣陽閱讀 2,458評論 1 15
  • 寫在前面的話: 這篇博客是我從這里“轉(zhuǎn)載”的背犯,為什么轉(zhuǎn)載兩個字加“”呢坏瘩?因為這絕不是簡單的復制粘貼,我花了五六個小...
    SmartSean閱讀 4,742評論 12 45
  • Java-Review-Note——4.多線程 標簽: JavaStudy PS:本來是分開三篇的漠魏,后來想想還是整...
    coder_pig閱讀 1,655評論 2 17
  • 該文章轉(zhuǎn)自:http://blog.csdn.net/evankaka/article/details/44153...
    加來依藍閱讀 7,355評論 3 87