在Java中,线程可以被标记为守护线程(Daemon Thread)或非守护线程(也称为用户线程,User Thread)。这两种线程的主要差异在于它们对Java虚拟机(JVM)终止行为的影响。
主要差异
- JVM终止条件:
- 非守护线程:只要至少有一个非守护线程在运行,JVM就会继续执行。只有当所有非守护线程都已终止时,JVM才会退出。
- 守护线程:守护线程是专门为其他线程(尤其是非守护线程)提供服务的。当JVM中只剩下守护线程时,JVM会立即退出,不考虑守护线程是否还在运行。
- 用途:
- 守护线程:通常用于执行“后台”任务,如垃圾收集器、JVM内部监视线程等。这些任务不需要阻止JVM的退出。
- 非守护线程:用于执行程序的主要任务,是用户编写程序时主要关心的线程。
创建有Daemon字眼的线程
在Java中,你可以通过调用线程的setDaemon(true)
方法将线程设置为守护线程。这必须在线程启动(即调用start()
方法)之前完成。一旦线程启动,就不能再更改其守护状态。
下面是一个简单的例子,演示如何创建一个守护线程:
java复制代码
public class DaemonThreadExample { |
|
public static void main(String[] args) { |
|
// 创建一个Thread实例 |
|
Thread daemonThread = new Thread(() -> { |
|
while (true) { |
|
try { |
|
// 模拟守护线程正在执行的任务 |
|
System.out.println("Daemon Thread is running"); |
|
Thread.sleep(1000); // 休眠1秒 |
|
} catch (InterruptedException e) { |
|
e.printStackTrace(); |
|
} |
|
} |
|
}); |
|
// 将线程设置为守护线程 |
|
daemonThread.setDaemon(true); |
|
// 启动线程 |
|
daemonThread.start(); |
|
// 主线程(非守护线程)执行完成后,JVM将退出,因为只剩下守护线程在运行 |
|
System.out.println("Main thread is ending."); |
|
} |
|
} |
在这个例子中,主线程(即main
方法所在的线程)会立即结束,因为它没有等待守护线程(daemonThread
)的完成。由于JVM中没有非守护线程在运行,JVM会退出,即使守护线程仍在运行。
注意:守护线程不能作为程序的主要任务线程,因为当JVM只剩下守护线程时,它会立即退出,这可能会导致未完成的任务或数据丢失。守护线程通常用于执行一些“清扫”工作或后台任务。