其实很多人,对守护线程并不理解。主要原因是: 测试很不好测,有外界因素干扰。
所以这篇文章,只是让你认识守护线程,理解守护线程,千万不要纠结于为什么用@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
最后再总结一下:
只要守护线程还在,其他线程都能正常运行。
其他线程全都运行完毕了,守护线程就自动销毁。