1. 程式人生 > >Java - 線程優先級和守護線程

Java - 線程優先級和守護線程

call htm read follow 基礎篇 int 結束 machine ted

Java多線程系列--“基礎篇”10之 線程優先級和守護線程

概要

本章,會對守護線程和線程優先級進行介紹。涉及到的內容包括:
1. 線程優先級的介紹
2. 線程優先級的示例
3. 守護線程的示例

轉載請註明出處:http://www.cnblogs.com/skywang12345/p/3479982.html

1. 線程優先級的介紹

java 中的線程優先級的範圍是1~10,默認的優先級是5。“高優先級線程”會優先於“低優先級線程”執行。

java 中有兩種線程:用戶線程守護線程。可以通過isDaemon()方法來區別它們:如果返回false,則說明該線程是“用戶線程”;否則就是“守護線程”。
用戶線程一般用戶執行用戶級任務,而守護線程也就是“後臺線程”,一般用來執行後臺任務。需要註意的是:Java虛擬機在“用戶線程”都結束後會後退出。

JDK 中關於線程優先級和守護線程的介紹如下:

技術分享
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon. When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.

When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:

The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method. 
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
技術分享

大致意思是:

技術分享
每個線程都有一個優先級。“高優先級線程”會優先於“低優先級線程”執行。每個線程都可以被標記為一個守護進程或非守護進程。在一些運行的主線程中創建新的子線程時,子線程的優先級被設置為等於“創建它的主線程的優先級”,當且僅當“創建它的主線程是守護線程”時“子線程才會是守護線程”。

當Java虛擬機啟動時,通常有一個單一的非守護線程(該線程通過是通過main()方法啟動)。JVM會一直運行直到下面的任意一個條件發生,JVM就會終止運行:
(01) 調用了exit()方法,並且exit()有權限被正常執行。
(02) 所有的“非守護線程”都死了(即JVM中僅僅只有“守護線程”)。

每一個線程都被標記為“守護線程”或“用戶線程”。當只有守護線程運行時,JVM會自動退出。
技術分享

2. 線程優先級的示例

我們先看看優先級的示例

技術分享
 1 class MyThread extends Thread{  
 2     public MyThread(String name) {
 3         super(name);
 4     }
 5 
 6     public void run(){
 7         for (int i=0; i<5; i++) {
 8             System.out.println(Thread.currentThread().getName()
 9                     +"("+Thread.currentThread().getPriority()+ ")"
10                     +", loop "+i);
11         }
12     } 
13 }; 
14 
15 public class Demo {  
16     public static void main(String[] args) {  
17 
18         System.out.println(Thread.currentThread().getName()
19                 +"("+Thread.currentThread().getPriority()+ ")");
20 
21         Thread t1=new MyThread("t1");    // 新建t1
22         Thread t2=new MyThread("t2");    // 新建t2
23         t1.setPriority(1);                // 設置t1的優先級為1
24         t2.setPriority(10);                // 設置t2的優先級為10
25         t1.start();                        // 啟動t1
26         t2.start();                        // 啟動t2
27     }  
28 }
技術分享

運行結果

技術分享
main(5)
t1(1), loop 0
t2(10), loop 0
t1(1), loop 1
t2(10), loop 1
t1(1), loop 2
t2(10), loop 2
t1(1), loop 3
t2(10), loop 3
t1(1), loop 4
t2(10), loop 4
技術分享

結果說明
(01) 主線程main的優先級是5。
(02) t1的優先級被設為1,而t2的優先級被設為10。cpu在執行t1和t2的時候,根據時間片輪循調度,所以能夠並發執行。

3. 守護線程的示例

下面是守護線程的示例。

技術分享
 1 // Demo.java
 2 class MyThread extends Thread{  
 3     public MyThread(String name) {
 4         super(name);
 5     }
 6 
 7     public void run(){
 8         try {
 9             for (int i=0; i<5; i++) {
10                 Thread.sleep(3);
11                 System.out.println(this.getName() +"(isDaemon="+this.isDaemon()+ ")" +", loop "+i);
12             }
13         } catch (InterruptedException e) {
14         }
15     } 
16 }; 
17 
18 class MyDaemon extends Thread{  
19     public MyDaemon(String name) {
20         super(name);
21     }
22 
23     public void run(){
24         try {
25             for (int i=0; i<10000; i++) {
26                 Thread.sleep(1);
27                 System.out.println(this.getName() +"(isDaemon="+this.isDaemon()+ ")" +", loop "+i);
28             }
29         } catch (InterruptedException e) {
30         }
31     } 
32 }
33 public class Demo {  
34     public static void main(String[] args) {  
35 
36         System.out.println(Thread.currentThread().getName()
37                 +"(isDaemon="+Thread.currentThread().isDaemon()+ ")");
38 
39         Thread t1=new MyThread("t1");    // 新建t1
40         Thread t2=new MyDaemon("t2");    // 新建t2
41         t2.setDaemon(true);                // 設置t2為守護線程
42         t1.start();                        // 啟動t1
43         t2.start();                        // 啟動t2
44     }  
45 }
技術分享

運行結果

技術分享
main(isDaemon=false)
t2(isDaemon=true), loop 0
t2(isDaemon=true), loop 1
t1(isDaemon=false), loop 0
t2(isDaemon=true), loop 2
t2(isDaemon=true), loop 3
t1(isDaemon=false), loop 1
t2(isDaemon=true), loop 4
t2(isDaemon=true), loop 5
t2(isDaemon=true), loop 6
t1(isDaemon=false), loop 2
t2(isDaemon=true), loop 7
t2(isDaemon=true), loop 8
t2(isDaemon=true), loop 9
t1(isDaemon=false), loop 3
t2(isDaemon=true), loop 10
t2(isDaemon=true), loop 11
t1(isDaemon=false), loop 4
t2(isDaemon=true), loop 12
技術分享

結果說明
(01) 主線程main是用戶線程,它創建的子線程t1也是用戶線程。
(02) t2是守護線程。在“主線程main”和“子線程t1”(它們都是用戶線程)執行完畢,只剩t2這個守護線程的時候,JVM自動退出。

Java - 線程優先級和守護線程