在Java中,线程分为用户线程和守护线程两种类型。用户线程是高优先级线程,主要执行业务逻辑,可以阻止JVM的退出。守护线程是低优先级线程,通常用于执行后台任务,不会阻止JVM的退出,生命周期依赖于用户线程。可以通过调用Thread
类的setDaemon(boolean on)
方法来设置线程为守护线程,但必须在调用start()
方法之前设置。
用户线程(User Thread)
-
定义:
- 用户线程是高优先级线程,是程序中主要的执行线程。
-
特点:
- 当所有的用户线程都终止时,Java虚拟机(JVM)会退出。
- 用户线程可以阻止JVM的退出。即使主线程已经结束,只要还有用户线程在运行,JVM就不会退出。
-
使用场景:
- 用户线程通常用于执行主要的业务逻辑和任务。
守护线程(Daemon Thread)
-
定义:
- 守护线程是低优先级线程,通常用于执行后台任务,如垃圾回收、内存管理等。
-
特点:
- 守护线程不会阻止JVM的退出。当所有的用户线程都终止时,JVM会退出,无论守护线程是否还在运行。
- 守护线程的生命周期依赖于用户线程。如果所有的用户线程都终止了,守护线程也会自动终止。
-
使用场景:
- 守护线程通常用于执行一些后台任务,如日志记录、性能监控、资源清理等。
设置线程为守护线程
可以通过调用Thread
类的setDaemon(boolean on)
方法来设置线程为守护线程。需要注意的是,必须在调用start()
方法之前设置线程为守护线程,否则会抛出IllegalThreadStateException
异常。
示例代码
public class DaemonThreadExample {
public static void main(String[] args) {
Thread userThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("User thread is running: " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread daemonThread = new Thread(() -> {
while (true) {
System.out.println("Daemon thread is running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
daemonThread.setDaemon(true); // 设置为守护线程
userThread.start();
daemonThread.start();
}
}
在这个示例中,userThread
是一个用户线程,daemonThread
是一个守护线程。当userThread
执行完毕后,JVM会退出,daemonThread
也会随之终止。
总结
- 用户线程:高优先级线程,主要执行业务逻辑,可以阻止JVM的退出。
- 守护线程:低优先级线程,执行后台任务,不会阻止JVM的退出,生命周期依赖于用户线程。