Java 守护线程
在 Java 并發編程實踐或看涉及到 Java 并發相關的代碼時,經常會遇到一些線程(比如做 metrics 統計的線程等)會通過?setDaemon()?方法設置將該線程的 daemon 變量設置為 True,也就是將這個線程設置為了守護線程(daemon thread),那么什么是守護線程呢?或者說守護線程與非守護線程(普通線程)的區別在什么地方呢?這個就是本文主要講述的內容。
守護線程
一般來說,Java 中的線程可以分為兩種:守護線程和普通線程。在 JVM 剛啟動時,它創建的所有線程,除了主線程(main thread)外,其他的線程都是守護線程(比如:垃圾收集器、以及其他執行輔助操作的線程)。
當創建一個新線程時,新線程將會繼承它線程的守護狀態,默認情況下,主線程創建的所有線程都是普通線程。
什么情況下會需要守護線程呢?一般情況下是,當我們希望創建一個線程來執行一些輔助的工作,但是又不希望這個線程阻礙 JVM 的關閉,在這種情況下,我們就需要使用守護線程了。
守護線程的作用
守護線程與普通線程唯一的區別是:當線程退出時,JVM 會檢查其他正在運行的線程,如果這些線程都是守護線程,那么 JVM 會正常退出操作,但是如果有普通線程還在運行,JVM 是不會執行退出操作的。當 JVM 退出時,所有仍然存在的守護線程都將被拋棄,既不會執行 finally 部分的代碼,也不會執行 stack unwound 操作,JVM 會直接退出。
| When the JVM halts any remaining daemon threads are abandoned: 1. finally blocks are not executed, 2. stacks are not unwound - the JVM just exits. |
下面有個小示例,來自?What is a daemon thread in Java?,代碼如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | public class DaemonTest { public static void main(String[] args) { new WorkerThread().start(); try { Thread.sleep(7500); } catch (InterruptedException e) { // handle here exception } System.out.println("Main Thread ending"); } } class WorkerThread extends Thread { public WorkerThread() { // When false, (i.e. when it's a user thread), the Worker thread continues to run. // When true, (i.e. when it's a daemon thread), the Worker thread terminates when the main thread terminates. setDaemon(false); } public void run() { int count = 0; while (true) { System.out.println("Hello from Worker " + count++); try { sleep(5000); } catch (InterruptedException e) { // handle exception here } } } } |
當為普通線程時,輸出如下:
| Hello from Worker 0 Hello from Worker 1 Main Thread ending Hello from Worker 2 Hello from Worker 3 Hello from Worker 4 Hello from Worker 5 .... |
也就是說,此時即使主線程執行完了,JVM 也會等待 WorkerThread 執行完畢才會退出,而如果將該線程設置守護線程的話,輸出如下:
| Hello from Worker 0 Hello from Worker 1 Main Thread ending |
在 main 線程執行完畢后,JVM 進程就退出了,不會 care WorkerThread 線程是否執行完畢。
參考:
- What is a daemon thread in Java?;
- 《Java 并發編程實戰》。
from:?http://matt33.com/2018/07/07/java-daemon-thread/?
總結
- 上一篇: Java 守护线程概述
- 下一篇: 深入理解Java Class文件格式