本文主要討論線程的各類屬性,包括:主線程、線程優先級、守護線程、線程組、處理未捕獲異常的處理器。java
public class Priority { @Test public void defaultPriority(){ int mainThreadPriority = Thread.currentThread().getPriority(); System.out.println("default priority is "+mainThreadPriority);//5 } @Test public void extendFather(){ Thread mainThread = Thread.currentThread(); mainThread.setPriority(4); int mainThreadPriority = mainThread.getPriority(); System.out.println("main thread's priority is "+mainThreadPriority);//4 Thread t1 = new Thread(() -> System.out.println(Thread.currentThread().getName()),"t1"); System.out.println("t1 thread's priority is "+t1.getPriority());//4 } }
相關API:數據庫
void setPriority(int priority) 設置線程優先級 int getPriority() 獲取線程優先級
備註:ide
1. 不要讓業務依賴於線程優先級。(優先級只能讓線程獲取更多的機會優先執行,但不一是必定會優先執行)spa
2. 通常狀況下,不會對線程設定優先級線程
守護線程code
void setDaemon(boolean isdaemon) 設置線程爲守護線程或者用戶線程。該方法必須在線程啓動以前調用。 boolean isDaemon() 判斷該線程是否爲後臺線程
線程組對象
public class ThreadGroupDemo { public static void print(){ Thread thread = Thread.currentThread(); System.out.println(thread.getThreadGroup().getName()+"-"+thread.getName()); } public static void main(String[] args) { ThreadGroup group = new ThreadGroup("Print Group"); new Thread(group, ThreadGroupDemo::print, "t1").start(); new Thread(group, ThreadGroupDemo::print, "t2").start(); group.list(); } }
補充:blog
未捕獲異常處理器繼承
線程的run()不能拋出任何被檢測的異常【由於Runnable接口中定義的run()沒有拋出異常,因此重寫run()時,不容許拋出異常,可使用try-catch捕獲異常】。可是,若是不被檢測的異常沒有使用try-catch處理,發生異常時會致使線程死亡。(好比下面這個例子,控制檯並無輸出「Endind?」)接口
public class UncaughtExceptionDemo implements Runnable{ @Override public void run() { int i = 1/0; System.out.println("Endind?"); } public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(1); service.execute(new UncaughtExceptionDemo()); } } /* log: ... Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero at concurrency.attributes.UncaughtExceptionDemo.run(UncaughtExceptionDemo.java:10) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) */
並且,在run中手動拋出了一個運行時異常,在main中使用try-catch處理異常,並未生效。(以下例,控制檯並未輸出"Current thread occurs exception.")
public class UncaughtExceptionDemo implements Runnable{ @Override public void run() { int i = 1/0; } public static void main(String[] args) { try{ ExecutorService service = Executors.newFixedThreadPool(1); service.execute(new UncaughtExceptionDemo()); } catch (RuntimeException e){ System.out.println("Current thread occurs exception."); } } } /* ... Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero at concurrency.attributes.UncaughtExceptionDemo.run(UncaughtExceptionDemo.java:10) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) */
那麼,應該如何處理線程中拋出的異常呢?事實上,異常發生後,在線程死亡以前,異常會被傳遞到一個用於未捕獲異常的處理器。可使用該處理器來處理線程中拋出的異常。
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadExceptionResolve implements Runnable{ @Override public void run() { int i = 1/0; System.out.println("Endind?"); } public static void main(String[] args) { //2. 爲全部的線程設置「異常處理器」 Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler()); //3. 建立並執行線程 ExecutorService service = Executors.newFixedThreadPool(1); service.execute(new ThreadExceptionResolve()); } } //1. 定義符合線程異常處理器規範的「異常處理器」 // 該處理器必須屬於一個實現Thread.UncaughtExceptionHandler接口的類 class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println("The acculation is error."); } } /* ... The acculation is error. */
安裝處理器的方式有兩種:可使用Thread的靜態方法setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)爲全部線程設置默認處理器,也可使用Thread的實例方法setUncaughtExceptionHandler(UncaughtExceptionHandler eh)爲摸一個線程設定處理器。若是線程沒有安裝處理器,此時的處理器就是該線程的ThreadGroup對象。
//爲全部線程設置默認處理器 Thread.setDefaultUncaughtExceptionHandler(handler); //爲指定線程設置處理器 Thread mainThread = Thread.currentThread(); mainThread.setUncaughtExceptionHandler(handler);