Java 守护线程
在 Java 并發(fā)編程實(shí)踐或看涉及到 Java 并發(fā)相關(guān)的代碼時,經(jīng)常會遇到一些線程(比如做 metrics 統(tǒng)計(jì)的線程等)會通過?setDaemon()?方法設(shè)置將該線程的 daemon 變量設(shè)置為 True,也就是將這個線程設(shè)置為了守護(hù)線程(daemon thread),那么什么是守護(hù)線程呢?或者說守護(hù)線程與非守護(hù)線程(普通線程)的區(qū)別在什么地方呢?這個就是本文主要講述的內(nèi)容。
守護(hù)線程
一般來說,Java 中的線程可以分為兩種:守護(hù)線程和普通線程。在 JVM 剛啟動時,它創(chuàng)建的所有線程,除了主線程(main thread)外,其他的線程都是守護(hù)線程(比如:垃圾收集器、以及其他執(zhí)行輔助操作的線程)。
當(dāng)創(chuàng)建一個新線程時,新線程將會繼承它線程的守護(hù)狀態(tài),默認(rèn)情況下,主線程創(chuàng)建的所有線程都是普通線程。
什么情況下會需要守護(hù)線程呢?一般情況下是,當(dāng)我們希望創(chuàng)建一個線程來執(zhí)行一些輔助的工作,但是又不希望這個線程阻礙 JVM 的關(guān)閉,在這種情況下,我們就需要使用守護(hù)線程了。
守護(hù)線程的作用
守護(hù)線程與普通線程唯一的區(qū)別是:當(dāng)線程退出時,JVM 會檢查其他正在運(yùn)行的線程,如果這些線程都是守護(hù)線程,那么 JVM 會正常退出操作,但是如果有普通線程還在運(yùn)行,JVM 是不會執(zhí)行退出操作的。當(dāng) JVM 退出時,所有仍然存在的守護(hù)線程都將被拋棄,既不會執(zhí)行 finally 部分的代碼,也不會執(zhí)行 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 } } } } |
當(dāng)為普通線程時,輸出如下:
| 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 .... |
也就是說,此時即使主線程執(zhí)行完了,JVM 也會等待 WorkerThread 執(zhí)行完畢才會退出,而如果將該線程設(shè)置守護(hù)線程的話,輸出如下:
| Hello from Worker 0 Hello from Worker 1 Main Thread ending |
在 main 線程執(zhí)行完畢后,JVM 進(jìn)程就退出了,不會 care WorkerThread 線程是否執(zhí)行完畢。
參考:
- What is a daemon thread in Java?;
- 《Java 并發(fā)編程實(shí)戰(zhàn)》。
from:?http://matt33.com/2018/07/07/java-daemon-thread/?
總結(jié)
- 上一篇: Java 守护线程概述
- 下一篇: 深入理解Java Class文件格式