其实很多人,对守护线程并不理解。主要原因是: 测试很不好测,有外界因素干扰。
所以这篇文章,只是让你认识守护线程,理解守护线程,千万不要纠结于为什么用@Test测试 和 用main方法测试。因为你如果反过来用@Test用main来测,结果刚刚相反。至于为什么:1.@Test 的4版本不支持多线程 2.main方法本身就是jvm启动的一个线程。没有足够理解多线程的时候,千万不要想这个问题。记得只看结果,不看过程。
今天就用两个例子,好好的扒一下 守护线程。
第一: 当没有守护线程的时候会发生什么 ?
首先先创建一个线程:
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
最后再总结一下:
只要守护线程还在,其他线程都能正常运行。
其他线程全都运行完毕了,守护线程就自动销毁。