其實很多人,對守護線程並不理解。主要原因是: 測試很不好測,有外界因素干擾。
所以這篇文章,只是讓你認識守護線程,理解守護線程,千萬不要糾結於爲什麼用@Test測試 和 用main方法測試。因爲你如果反過來用@Test用main來測,結果剛剛相反。至於爲什麼:1.@Test 的4版本不支持多線程 2.main方法本身就是jvm啓動的一個線程。沒有足夠理解多線程的時候,千萬不要想這個問題。記得只看結果,不看過程。
今天就用兩個例子,好好的扒一下 守護線程。
核心:當一個Java應用內只有守護線程時,Java虛擬機自然退出。
第一: 當沒有守護線程的時候會發生什麼 ?
首先先創建一個線程:
public class NotDaemonThread extends Thread {
public NotDaemonThread(String name) {
super(name);
}
@Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
然後我們來調用他: (這裏必須用@Test來測試)
@Test
public void test() {
NotDaemonThread thread1 = new NotDaemonThread("非守護線程 1");
NotDaemonThread thread2 = new NotDaemonThread("非守護線程 2");
thread1.start();
thread2.start();
for (int i = 0; i < 10; i++) {
System.out.println("程序執行中" + i);
}
System.out.println("程序執行完畢");
}
結果:證明了如果沒有守護線程,就不會等其他線程執行完畢之後,才停止程序。
程序執行中0
程序執行中1
程序執行中2
程序執行中3
程序執行中4
程序執行中5
程序執行中6
程序執行中7
程序執行中8
非守護線程 2: 0
非守護線程 1: 0
程序執行中9
程序執行完畢
第二:當有守護線程的時候
創建一個新線程,目前他是一個正常的線程,但是我準備將其做爲 守護線程
public class DaemonThread extends Thread {
@Override
public void run() {
while (true) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
}
創建一個新線程,想象他是一個需要正常運行程序的線程,他必須執行完畢,程序才能停止
public class UseThread extends Thread {
public UseThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
測試代碼:
public class Test {
/**
* 當一個Java應用內只有守護線程時,Java虛擬機自然退出。
* <p>
* 守護線程其實挺難理解的: 上面那句話是核心。
*
* @throws InterruptedException
*/
public static void main(String[] args) {
DaemonThread daemonThread = new DaemonThread();
Thread thread = new Thread(daemonThread, "守護線程");
// 標記DaemonThread爲守護線程
thread.setDaemon(true);
thread.start();
UseThread userThread = new UseThread("正在使用的線程");
// 啓動我們要正常使用的線程
userThread.start();
System.out.println("主線程被銷燬");
}
}
結果:程序最後的這句話已經打印,但是線程還是在執行中,當正在使用的線程執行到4,執行完畢之後,守護線程自動銷燬。
主線程被銷燬
守護線程
正在使用的線程: 0
守護線程
正在使用的線程: 1
守護線程
正在使用的線程: 2
守護線程
正在使用的線程: 3
守護線程
正在使用的線程: 4
最後再總結一下:
只要守護線程還在,其他線程都能正常運行。
其他線程全都運行完畢了,守護線程就自動銷燬。