1、区别
Java中有两类线程:用户线程和守护线程
守护线程一般用于在程序运行的时候提供一种通用服务,在主线程要结束前,如果发现程序中只剩下守护线程,那么jvm不会管守护线程的死活,直接结束整个程序应用。守护线程比较典型的用例是java中的垃圾回收线程。
我们新建一个线程的时候,默认新建的是用户线程,当主线程结束之前,如果发现线程中还有用户线程,那么主线程(或者说程序)不会立即停止,而是等待用户线程执行完才结束
也就是说,守护线程实际上没有什么话语权的,程序要结束的时候会查看用户线程,用户线程执行完了才真正的结束,但是如果发现只有守护线程了,就不会管它了,直接结束。
2、举例
(1)子线程是非守护线程(用户线程)
主线程调用:
public class ParentTest {
public static void main(String[] args) {
System.out.println("parent thread begin");
ChildThread c1 = new ChildThread("thread1");
ChildThread c2 = new ChildThread("thread2");
Thread t1 = new Thread(c1);
Thread t2 = new Thread(c2);
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("parent thread over");//注意的是这里的over并不是真正的over,只是做一个记号
}
}
子线程:
public class ChildThread implements Runnable{
private String name = null;
public ChildThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(this.name + "--child thread begin");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.name + "--child thread over");
}
}
执行结果:
可以看到的是,这里执行到“parent thread over”的地方,主线程是【想要结束】的,但是发现两个用户线程还在运行,所以等待它们运行完才结束
(2)子线程是守护线程
现在,我把上面两个线程设置为守护线程,再看看运行情况:
public class ParentTest {
public static void main(String[] args) {
System.out.println("parent thread begin");
ChildThread c1 = new ChildThread("thread1");
ChildThread c2 = new ChildThread("thread2");
Thread t1 = new Thread(c1);
Thread t2 = new Thread(c2);
t1.setDaemon(true);
t2.setDaemon(true);
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("parent thread over");
}
}
子线程依然是上面的代码,执行结果如下:
可以看到,执行到“parent thread over”的时候,主线程【要结束】了,但是发现只剩下守护线程了,所以直接结束,没有继续执行守护线程