本文目录导读:

我来详细介绍Java守护线程的创建方法和案例:
什么是守护线程
- 守护线程(Daemon Thread):在后台运行,为其他线程提供服务
- 用户线程:执行主要的业务逻辑
- 特点:当所有用户线程结束,JVM会自动退出,不等待守护线程完成
创建守护线程的基本方法
使用setDaemon(true)
public class DaemonThreadExample1 {
public static void main(String[] args) {
Thread daemonThread = new Thread(() -> {
while (true) {
try {
System.out.println("守护线程运行中...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// 设置为守护线程(必须在start之前)
daemonThread.setDaemon(true);
daemonThread.start();
System.out.println("主线程结束");
// 主线程结束后,JVM不会等待守护线程,直接退出
}
}
通过ThreadFactory创建
import java.util.concurrent.ThreadFactory;
public class DaemonThreadExample2 {
public static void main(String[] args) {
ThreadFactory daemonFactory = r -> {
Thread t = new Thread(r);
t.setDaemon(true);
t.setName("守护线程-" + System.currentTimeMillis());
return t;
};
Runnable task = () -> {
while (true) {
System.out.println(Thread.currentThread().getName() + " 运行中");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread daemonThread = daemonFactory.newThread(task);
daemonThread.start();
}
}
实际应用案例
案例1:后台日志记录器
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
public class LogDaemonDemo {
private static class LogWorker implements Runnable {
private volatile boolean running = true;
@Override
public void run() {
try (FileWriter writer = new FileWriter("app.log", true)) {
while (running) {
String log = LocalDateTime.now() + " - 系统运行正常\n";
writer.write(log);
writer.flush();
System.out.print(".");
Thread.sleep(2000);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
public void stop() {
this.running = false;
}
}
public static void main(String[] args) throws InterruptedException {
LogWorker logWorker = new LogWorker();
Thread logThread = new Thread(logWorker);
logThread.setDaemon(true);
logThread.start();
// 模拟主程序运行
System.out.println("主程序开始运行");
Thread.sleep(5000);
System.out.println("\n主程序结束");
// JVM自动退出,守护线程终止
}
}
案例2:监控和清理服务
public class MonitorDaemonDemo {
// 模拟心跳监控
static class HeartbeatMonitor implements Runnable {
@Override
public void run() {
int count = 0;
while (true) {
try {
System.out.println("[监控] 系统心跳检查 #" + (++count));
// 模拟检查系统资源
Runtime runtime = Runtime.getRuntime();
long usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024;
System.out.println("[监控] 当前内存使用: " + usedMemory + "MB");
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println("[监控] 监控服务中断");
break;
}
}
}
}
// 模拟缓存清理
static class CacheCleaner implements Runnable {
@Override
public void run() {
while (true) {
try {
System.out.println("[清理] 开始清理临时缓存...");
// 模拟清理操作
Thread.sleep(5000);
System.out.println("[清理] 缓存清理完成");
} catch (InterruptedException e) {
System.out.println("[清理] 清理服务中断");
break;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
// 创建监控守护线程
Thread monitorThread = new Thread(new HeartbeatMonitor());
monitorThread.setDaemon(true);
monitorThread.setName("监控线程");
// 创建清理守护线程
Thread cleanerThread = new Thread(new CacheCleaner());
cleanerThread.setDaemon(true);
cleanerThread.setName("清理线程");
monitorThread.start();
cleanerThread.start();
// 主业务逻辑
System.out.println("系统启动完成");
for (int i = 1; i <= 5; i++) {
System.out.println("处理业务请求 #" + i);
Thread.sleep(1500);
}
System.out.println("所有业务处理完成,系统即将关闭...");
// 主线程结束后,守护线程自动终止
}
}
案例3:超时监控器
public class TimeoutDaemonDemo {
// 模拟一个需要超时监控的任务
static class TimeoutMonitor implements Runnable {
private final long timeout;
private volatile boolean taskCompleted = false;
public TimeoutMonitor(long timeout) {
this.timeout = timeout;
}
@Override
public void run() {
long startTime = System.currentTimeMillis();
while (!taskCompleted) {
long elapsed = System.currentTimeMillis() - startTime;
if (elapsed > timeout) {
System.out.println("[超时监控] 任务执行超时!已执行: " + elapsed + "ms");
// 可以在这里执行超时处理逻辑
taskCompleted = true;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("[超时监控] 监控被中断");
break;
}
}
}
public void markCompleted() {
this.taskCompleted = true;
}
}
public static void main(String[] args) throws InterruptedException {
TimeoutMonitor monitor = new TimeoutMonitor(3000); // 3秒超时
Thread monitorThread = new Thread(monitor);
monitorThread.setDaemon(true);
monitorThread.start();
// 模拟一个长时间运行的任务
System.out.println("开始执行耗时任务...");
Thread.sleep(5000); // 模拟5秒的任务
monitor.markCompleted();
System.out.println("主程序结束");
}
}
重要注意事项
必须在线程启动前设置
// 正确方式 Thread t = new Thread(task); t.setDaemon(true); t.start(); // 错误方式 - 会抛出IllegalThreadStateException Thread t = new Thread(task); t.start(); t.setDaemon(true); // 异常!
检查是否为守护线程
public class CheckDaemonDemo {
public static void main(String[] args) {
Thread userThread = new Thread(() -> {
System.out.println("用户线程是否守护: " + Thread.currentThread().isDaemon());
});
userThread.start();
Thread daemonThread = new Thread(() -> {
System.out.println("守护线程是否守护: " + Thread.currentThread().isDaemon());
});
daemonThread.setDaemon(true);
daemonThread.start();
System.out.println("主线程是否守护: " + Thread.currentThread().isDaemon());
}
}
适用场景
- 后台日志记录
- 垃圾回收监控
- 系统资源监控
- 缓存清理
- 定时备份
- 性能统计
守护线程是Java中非常有用的特性,适用于需要持续运行但不需要在程序结束后继续存在的后台服务,创建简单,但要注意必须在start()之前调用setDaemon(true),并且理解JVM退出时不会等待守护线程完成的特点。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播