qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          Java并發編程:守護線程

          Java中有兩類線程:用戶線程(UserThread)、守護線程(DaemonThread)。

            所謂守護線程,是指在程序運行的時候在后臺提供一種通用服務的線程,比如垃圾回收線程就是一個很稱職的守護者,并且這種線程并不屬于程序中不可或缺的部分。因此,當所有的非守護線程結束時,程序也就終止了,同時會殺死進程中的所有守護線程。反過來說,只要任何非守護線程還在運行,程序就不會終止。

            用戶線程和守護線程兩者幾乎沒有區別,唯一的不同之處就在于虛擬機的離開:如果用戶線程已經全部退出運行了,只剩下守護線程存在了,虛擬機也就退出了。因為沒有了被守護者,守護線程也就沒有工作可做了,也就沒有繼續運行程序的必要了。

            將線程轉換為守護線程可以通過調用Thread對象的setDaemon(true)方法來實現。在使用守護線程時需要注意一下幾點:

            (1)thread.setDaemon(true)必須在thread.start()之前設置,否則會跑出一個IllegalThreadStateException異常。你不能把正在運行的常規線程設置為守護線程。

            (2)在Daemon線程中產生的新線程也是Daemon的。

            (3)守護線程應該永遠不去訪問固有資源,如文件、數據庫,因為它會在任何時候甚至在一個操作的中間發生中斷。

            代碼示例:

          1. import java.util.concurrent.TimeUnit;  
          2. /** 
          3. * 守護線程 
          4. */ 
          5. public class Daemons {  
          6. /** 
          7. * @param args 
          8. * @throws InterruptedException  
          9. */ 
          10. public static void main(String[] args) throws InterruptedException {  
          11. Thread d = new Thread(new Daemon());  
          12. d.setDaemon(true); //必須在啟動線程前調用 
          13. d.start();  
          14. System.out.println("d.isDaemon() = " + d.isDaemon() + ".");  
          15. TimeUnit.SECONDS.sleep(1);  
          16. }  
          17. }  
          18. class DaemonSpawn implements Runnable {  
          19. public void run() {  
          20. while (true) {  
          21. Thread.yield();  
          22. }  
          23. }  
          24. }  
          25. class Daemon implements Runnable {  
          26. private Thread[] t = new Thread[10];  
          27. public void run() {  
          28. for (int i=0; i<t.length; i++) {  
          29. t[i] = new Thread(new DaemonSpawn());  
          30. t[i].start();  
          31. System.out.println("DaemonSpawn " + i + " started.");  
          32. }  
          33. for (int i=0; i<t.length; i++) {  
          34. System.out.println("t[" + i + "].isDaemon() = " +  
          35. t[i].isDaemon() + ".");  
          36. }  
          37. while (true) {  
          38. Thread.yield();  
          39. }  
          40. }  
          41. }

            運行結果:

          1. d.isDaemon() = true.  
          2. DaemonSpawn 0 started.  
          3. DaemonSpawn 1 started.  
          4. DaemonSpawn 2 started.  
          5. DaemonSpawn 3 started.  
          6. DaemonSpawn 4 started.  
          7. DaemonSpawn 5 started.  
          8. DaemonSpawn 6 started.  
          9. DaemonSpawn 7 started.  
          10. DaemonSpawn 8 started.  
          11. DaemonSpawn 9 started.  
          12. t[0].isDaemon() = true.  
          13. t[1].isDaemon() = true.  
          14. t[2].isDaemon() = true.  
          15. t[3].isDaemon() = true.  
          16. t[4].isDaemon() = true.  
          17. t[5].isDaemon() = true.  
          18. t[6].isDaemon() = true.  
          19. t[7].isDaemon() = true.  
          20. t[8].isDaemon() = true.  
          21. t[9].isDaemon() = true.

           以上結果說明了守護線程中產生的新線程也是守護線程。

            如果將mian函數中的TimeUnit.SECONDS.sleep(1);注釋掉,運行結果如下:

          1. d.isDaemon() = true.  
          2. DaemonSpawn 0 started.  
          3. DaemonSpawn 1 started.  
          4. DaemonSpawn 2 started.  
          5. DaemonSpawn 3 started.  
          6. DaemonSpawn 4 started.  
          7. DaemonSpawn 5 started.  
          8. DaemonSpawn 6 started.  
          9. DaemonSpawn 7 started.  
          10. DaemonSpawn 8 started.  
          11. DaemonSpawn 9 started.

            以上結果說明了如果用戶線程已經全部退出運行了,只剩下守護線程存在了,虛擬機也就退出了。下面的例子也說明了這個問題。

            代碼示例:

          1. import java.util.concurrent.TimeUnit;  
          2. /**  
          3. * Finally shoud be always run ?  
          4. */  
          5. public class DaemonsDontRunFinally {  
          6. /**  
          7. * @param args  
          8. */  
          9. public static void main(String[] args) {  
          10. Thread t = new Thread(new ADaemon());  
          11. t.setDaemon(true);  
          12. t.start();  
          13. }  
          14. }  
          15. class ADaemon implements Runnable {  
          16. public void run() {  
          17. try {  
          18. System.out.println("start ADaemon...");  
          19. TimeUnit.SECONDS.sleep(1);  
          20. } catch (InterruptedException e) {  
          21. System.out.println("Exiting via InterruptedException");  
          22. } finally {  
          23. System.out.println("This shoud be always run ?");  
          24. }  
          25. }  
          26. }

            運行結果:

            start ADaemon...

            如果將main函數中的t.setDaemon(true);注釋掉,運行結果如下:

            start ADaemon...

            This shoud be always run ?



          posted on 2011-12-31 10:34 順其自然EVO 閱讀(199) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2011年12月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 叶城县| 灵台县| 阿拉善盟| 司法| 东阿县| 洪泽县| 高要市| 沁源县| 郴州市| 惠州市| 白银市| 方正县| 遂平县| 平舆县| 河南省| 修武县| 新泰市| 赤壁市| 泗水县| 廊坊市| 南和县| 西吉县| 墨竹工卡县| 定边县| 贞丰县| 新郑市| 游戏| 东平县| 宁武县| 都兰县| 无为县| 淮南市| 革吉县| 建宁县| 波密县| 二连浩特市| 吴堡县| 长阳| 滦平县| 汉源县| 镇雄县|