Thread官方說明 https://developer.android.google.cn/reference/java/lang/Thread Thread是程式中執行的線程。Java虛擬機允許應用程式同時運行多個執行線程。 每個線程都可設置優先順序別。優先順序別高的線程優先於優先順序別低的線程執行。 ...
Thread官方說明
https://developer.android.google.cn/reference/java/lang/Thread
Thread是程式中執行的線程。Java虛擬機允許應用程式同時運行多個執行線程。
每個線程都可設置優先順序別。優先順序別高的線程優先於優先順序別低的線程執行。線程可能是守護進程(Daemon),也可能是非守護進程(Non-daemon)。當在某個線程的代碼中創建一個新的Thread對象時,新線程的優先順序初始設置等於創建線程的優先順序,並且當且僅當創建線程是守護進程時新的Thread才是守護進程線程。
當Java虛擬機啟動時,通常會有一個非守護線程(通常會調用某個指定類的main方法)。Java虛擬機將繼續執行線程,直到出現以下任一情況:
- Runtime類的exit方法已經被調用並且安全管理器允許退出操作發生。
- 所有非守護線程已經退出,或者通過調用run方法返回或通過拋出一個run方法的異常。
有兩種方法可以創建一個新的執行線程。一種是將一個類聲明為Thread的子類。這個子類應該重寫Thread類的run方法。然後可以分配和啟動子類的一個實例。例如,計算大於某個值的素數的線程:
class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } }
下麵的代碼會創建一個線程並執行:
PrimeThread p = new PrimeThread(143); p.start();
另一種創建線程的方式是聲明一個實現了Runnable介面的類,然後實現了run方法。 然後可以分配一個類的實例,在創建線程時作為參數傳遞,然後啟動線程。 示例如下:
class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } }
下麵的代碼會創建一個線程並開始執行:
PrimeRun p = new PrimeRun(143); new Thread(p).start();
每個線程都有一個用於標識的名稱。 多個線程可能具有相同的名稱。 如果在創建線程時未指定名稱,則系統會自動為其生成新名稱。除非另有說明,否則將null參數傳遞給此類中的構造函數或方法將導致拋出NullPointerException。
守護線程(daemon)和用戶線程(User Thread)
所謂守護線程就是運行在程式後臺的線程,程式的主線程Main(比方java程式一開始啟動時創建的那個線程)不會是守護線程 。Daemon thread在Java裡面的定義是,如果虛擬機中只有Daemon thread 在運行,則虛擬機退出。通常Daemon線程用來為User線程提供某些服務。程式的main()方法線程是一個User線程,User線程創建的線程為User線程。當所有的Non-daemon線程結束後,JVM才會結束。
通過在一個線程對象上調用setDaemon(true),可以將user線程創建的線程明確地設置成Daemon線程。例如,時鐘處理線程、idle線程、垃圾回收線程、屏幕更新線程等,都是Daemon線程。通常新創建的線程會從創建它的線程哪裡繼承daemon狀態,除非明確地線上程對象上調用setDaemon方法來改變daemon狀態。
需要註意的是,setDaemon()方法必須在調用線程的start()方法之前調用。一旦一個線程開始執行(如,調用了start()方法),它的daemon狀態不能再修改。通過方法isDaemon()可以知道一個線程是否Daemon線程。
總之,必須等所有的Non-daemon線程都運行結束了,只剩下daemon的時候,JVM才會停下來,註意Main主程式是Non-daemon線程,預設產生的線程全部是Non-daemon線程。