Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)
用户线程即运行在前台的线程,而守护线程是运行在后台的线程。 守护线程作用是为其他前台线程的运行提供便利服务,仅在普通、非守护线程仍然运行时才需要,如果当前进程中只剩守护线程了,进程会直接结束(不管当前有多少守护线程都是一样的)。
比如垃圾回收线程就是一个守护线程。当VM检测仅剩一个守护线程,而用户线程都已经退出运行时,VM就会退出,因为如果没有了守护者,也就没有继续运行程序的必要了。如果有非守护线程仍然活着,VM就不会退出。
用户在编写程序时也可以自己设置守护线程。用户可以用Thread的setDaemon(true)方法设置当前线程为守护线程。
虽然守护线程可能非常有用,但必须小心确保其它所有非守护线程消亡时,不会由于它的终止而产生任何危害。因为你不可能知道在所有的用户线程退出运行前,守护线程是否已经完成了预期的服务任务。一旦所有的用户线程退出了,虚拟机也就退出运行了。因此,不要再守护线程中执行业务逻辑操作(比如对数据的读写等)。
还有几点:
- setDaemon(true)必须在调用线程的start()方法之前设置,否则会抛出IllegalThreadStateException异常。
- 在守护线程中产生的新线程也是守护线程
- 不要认为所有的应用都可以分配给守护线程来进行服务,比如读写操作或者计算逻辑。
package MyThread;
public class DeamonThread {
static class ThreadDemo implements Runnable {
public void run() {
while (true) {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
Thread daemonThread = new Thread(new ThreadDemo());
daemonThread.setName("daemonThread");
// 设置为守护进程
daemonThread.setDaemon(true);
daemonThread.start();
Thread daemonThread2 = new Thread(new ThreadDemo());
daemonThread2.setDaemon(true);
daemonThread2.setName("daemonThread2");
daemonThread2.start();
Thread t = new Thread(new ThreadDemo());
t.setName("t");
t.start();
}
}
运行结果:
如果同时开启用户线程跟守护线程,守护线程将与用户线程一起不停地运行下去
如果只开启了守护线程(即使有2个),当主线程结束的时候,守护线程也一起跟着结束了
如果是用户线程,即使主线程结束了,用户线程也是不会结束的