<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ゞ沉默是金ゞ

    魚(yú)離不開(kāi)水,但是沒(méi)有說(shuō)不離開(kāi)哪滴水.
    posts - 98,comments - 104,trackbacks - 0

    很多核心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)來(lái)實(shí)現(xiàn),當(dāng)你打算多重繼承時(shí),優(yōu)先選擇實(shí)現(xiàn) Runnable。

    2.Thread.start ()與 Thread.run ()有什么區(qū)別?

    Thread.start ()方法(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 類(lèi)而造成的 Java 的多繼承問(wèn)題。

    4.什么是 ThreadLocal 類(lèi),怎么使用它?

    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è)類(lèi)中,這個(gè)類(lèi)用來(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 類(lèi)作為一個(gè)單例類(lèi)時(shí),數(shù)據(jù)庫(kù)鏈接(connection)被每一個(gè)線程獨(dú)立的維護(hù),互不影響。(基于線程的單例)

    ThreadLocal 難于理解,下面這些引用連接有助于你更好的理解它。

    Good article on ThreadLocal on IBM DeveloperWorks 》、《理解 ThreadLocal》、《Managing data : Good example》、《Refer Java API Docs

    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 的子類(lèi),所以該異常不一定要捕獲(盡管你可以捕獲只要你愿意).作為 RuntimeException,此類(lèi)異常不會(huì)在 wait (),notify (),notifyAll ()的方法簽名提及。

    6.Sleep ()、suspend ()和 wait ()之間有什么區(qū)別?

    Thread.sleep ()使當(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)前線程有效,一個(gè)常見(jiàn)的錯(cuò)誤是調(diào)用t.sleep (),(這里的t是一個(gè)不同于當(dāng)前線程的線程)。即便是執(zhí)行t.sleep (),也是當(dāng)前線程進(jìn)入睡眠,而不是t線程。t.suspend ()是過(guò)時(shí)的方法,使用 suspend ()導(dǎo)致線程進(jìn)入停滯狀態(tài),該線程會(huì)一直持有對(duì)象的監(jiān)視器,suspend ()容易引起死鎖問(wèn)題。

    object.wait ()使當(dāng)前線程出于“不可運(yùn)行”狀態(tài),和 sleep ()不同的是 wait 是 object 的方法而不是 thread。調(diào)用 object.wait ()時(shí),線程先要獲取這個(gè)對(duì)象的對(duì)象鎖,當(dāng)前線程必須在鎖對(duì)象保持同步,把當(dāng)前線程添加到等待隊(duì)列中,隨后另一線程可以同步同一個(gè)對(duì)象鎖來(lái)調(diào)用 object.notify (),這樣將喚醒原來(lái)等待中的線程,然后釋放該鎖。基本上 wait ()/notify ()與 sleep ()/interrupt ()類(lèi)似,只是前者需要獲取對(duì)象鎖。

    7.在靜態(tài)方法上使用同步時(shí)會(huì)發(fā)生什么事?

    同步靜態(tài)方法時(shí)會(huì)獲取該類(lèi)的“Class”對(duì)象,所以當(dāng)一個(gè)線程進(jìn)入同步的靜態(tài)方法中時(shí),線程監(jiān)視器獲取類(lèi)本身的對(duì)象鎖,其它線程不能進(jìn)入這個(gè)類(lèi)的任何靜態(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 類(lèi)有兩個(gè)方法 synchronizedMethod1()和 method1(),MyThread 類(lèi)在獨(dú)立的線程中調(diào)用這兩個(gè)方法。

    1. public class Common {  
    2.    
    3. public synchronized void synchronizedMethod1() {  
    4. System.out.println ("synchronizedMethod1 called");  
    5. try {  
    6. Thread.sleep (1000);  
    7. } catch (InterruptedException e) {  
    8. e.printStackTrace ();  
    9. }  
    10. System.out.println ("synchronizedMethod1 done");  
    11. }  
    12. public void method1() {  
    13. System.out.println ("Method 1 called");  
    14. try {  
    15. Thread.sleep (1000);  
    16. } catch (InterruptedException e) {  
    17. e.printStackTrace ();  
    18. }  
    19. System.out.println ("Method 1 done");  
    20. }  
    1. public class MyThread extends Thread {  
    2. private int id = 0;  
    3. private Common common;  
    4.    
    5. public MyThread (String name, int no, Common object) {  
    6. super(name);  
    7. common = object;  
    8. id = no;  
    9. }  
    10.    
    11. public void run () {  
    12. System.out.println ("Running Thread" + this.getName ());  
    13. try {  
    14. if (id == 0) {  
    15. common.synchronizedMethod1();  
    16. } else {  
    17. common.method1();  
    18. }  
    19. } catch (Exception e) {  
    20. e.printStackTrace ();  
    21. }  
    22. }  
    23.    
    24. public static void main (String[] args) {  
    25. Common c = new Common ();  
    26. MyThread t1 = new MyThread ("MyThread-1", 0, c);  
    27. MyThread t2 = new MyThread ("MyThread-2", 1, c);  
    28. t1.start ();  
    29. t2.start ();  
    30. }  
    31. }  

    這里是程序的輸出:

    1. Running ThreadMyThread-1  
    2. synchronizedMethod1 called  
    3. Running ThreadMyThread-2  
    4. Method 1 called  
    5. synchronizedMethod1 done  
    6. 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 類(lèi)有 synchronizedMethod1()和 synchronizedMethod2()方法,MyThread 調(diào)用這兩個(gè)方法。

    1. public class Common {  
    2. public synchronized void synchronizedMethod1() {  
    3. System.out.println ("synchronizedMethod1 called");  
    4. try {  
    5. Thread.sleep (1000);  
    6. } catch (InterruptedException e) {  
    7. e.printStackTrace ();  
    8. }  
    9. System.out.println ("synchronizedMethod1 done");  
    10. }  
    11.    
    12. public synchronized void synchronizedMethod2() {  
    13. System.out.println ("synchronizedMethod2 called");  
    14. try {  
    15. Thread.sleep (1000);  
    16. } catch (InterruptedException e) {  
    17. e.printStackTrace ();  
    18. }  
    19. System.out.println ("synchronizedMethod2 done");  
    20. }  
    1. public class MyThread extends Thread {  
    2. private int id = 0;  
    3. private Common common;  
    4.    
    5. public MyThread (String name, int no, Common object) {  
    6. super(name);  
    7. common = object;  
    8. id = no;  
    9. }  
    10.    
    11. public void run () {  
    12. System.out.println ("Running Thread" + this.getName ());  
    13. try {  
    14. if (id == 0) {  
    15. common.synchronizedMethod1();  
    16. } else {  
    17. common.synchronizedMethod2();  
    18. }  
    19. } catch (Exception e) {  
    20. e.printStackTrace ();  
    21. }  
    22. }  
    23.    
    24. public static void main (String[] args) {  
    25. Common c = new Common ();  
    26. MyThread t1 = new MyThread ("MyThread-1", 0, c);  
    27. MyThread t2 = new MyThread ("MyThread-2", 1, c);  
    28. t1.start ();  
    29. t2.start ();  
    30. }  

    10.什么是死鎖

    死鎖就是兩個(gè)或兩個(gè)以上的線程被無(wú)限的阻塞,線程之間相互等待所需資源。這種情況可能發(fā)生在當(dāng)兩個(gè)線程嘗試獲取其它資源的鎖,而每個(gè)線程又陷入無(wú)限等待其它資源鎖的釋放,除非一個(gè)用戶(hù)進(jìn)程被終止。就 JavaAPI 而言,線程死鎖可能發(fā)生在一下情況。

    • 當(dāng)兩個(gè)線程相互調(diào)用 Thread.join ()
    • 當(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í)行 Object.wait (0),參數(shù)為 0 的 wait 方法。程序?qū)l(fā)生活鎖直到在相應(yīng)的對(duì)象上有線程調(diào)用 Object.notify ()或者 Object.notifyAll ()。
    • 當(dāng)所有線程卡在無(wú)限循環(huán)中。

    這里的問(wèn)題并不詳盡,我相信還有很多重要的問(wèn)題并未提及,您認(rèn)為還有哪些問(wèn)題應(yīng)該包括在上面呢?歡迎在評(píng)論中分享任何形式的問(wèn)題與建議。

    sd.csdn.net/a/20120528/2806046.html
    posted on 2012-06-14 19:00 ゞ沉默是金ゞ 閱讀(273) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 日韩欧毛片免费视频| 国产免费观看黄AV片| 99久久国产亚洲综合精品| 国产成人免费永久播放视频平台 | 亚洲伊人成无码综合网| 免费午夜爽爽爽WWW视频十八禁| 一级做a爱过程免费视| 亚洲精品国产肉丝袜久久| 国产美女做a免费视频软件| 国产在线播放线91免费| 亚洲a视频在线观看| 亚洲人成影院在线观看| 日本阿v免费费视频完整版| 男女男精品网站免费观看| 亚洲国产成人久久三区| 久久影视国产亚洲| 永久免费AV无码国产网站| 成人久久免费网站| 国产综合成人亚洲区| 亚洲精品在线观看视频| 亚洲人成人无码网www国产| 成年在线观看网站免费| 国产三级在线免费| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲精品美女久久久久| 亚洲国产一区视频| 国产精品成人免费一区二区| 中文字幕免费在线看| 亚洲欧美成人av在线观看| 久久久久亚洲Av片无码v| 亚洲国产人成中文幕一级二级| 全免费毛片在线播放| 黄色网站软件app在线观看免费| 亚洲欧美在线x视频| 亚洲kkk4444在线观看| 亚洲一区影音先锋色资源| 久久精品国产精品亚洲| 免费看www视频| 国产高清免费视频| 午夜影院免费观看| A国产一区二区免费入口|