本文目录导读:

我将为您提供几个Java守护进程的完整案例,从基础到进阶。
基础守护进程案例
简单后台日志守护进程
public class BasicDaemonExample {
public static void main(String[] args) {
// 创建守护线程
Thread daemonThread = new Thread(() -> {
int count = 0;
while (true) {
try {
Thread.sleep(1000);
count++;
System.out.println("[守护线程] 后台日志记录 - " + count + "秒");
} catch (InterruptedException e) {
System.out.println("守护线程被中断");
break;
}
}
});
// 设置为守护线程
daemonThread.setDaemon(true);
daemonThread.setName("后台日志守护线程");
daemonThread.start();
System.out.println("主线程开始执行...");
// 主线程运行5秒后结束
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程结束,守护线程也随之结束");
}
}
实际业务场景案例
定时任务调度守护进程
import java.time.LocalTime;
import java.util.concurrent.*;
public class ScheduledTaskDaemon {
private static class TaskScheduler {
private final ScheduledExecutorService scheduler;
private final AtomicBoolean isRunning = new AtomicBoolean(false);
public TaskScheduler() {
// 使用守护线程工厂创建调度器
scheduler = Executors.newScheduledThreadPool(2, r -> {
Thread t = new Thread(r);
t.setDaemon(true); // 设置为守护线程
t.setName("任务调度器-" + System.nanoTime());
return t;
});
}
public void startScheduledTasks() {
if (isRunning.compareAndSet(false, true)) {
System.out.println("启动定时任务...");
// 每2秒执行一次的任务
scheduler.scheduleAtFixedRate(() -> {
cleanupOldData();
}, 0, 2, TimeUnit.SECONDS);
// 延迟5秒后每3秒执行的任务
scheduler.scheduleWithFixedDelay(() -> {
checkSystemHealth();
}, 5, 3, TimeUnit.SECONDS);
}
}
private void cleanupOldData() {
System.out.println("[" + LocalTime.now() + "] 清理过期数据...");
}
private void checkSystemHealth() {
System.out.println("[" + LocalTime.now() + "] 检查系统健康状态...");
}
public void shutdown() {
scheduler.shutdown();
isRunning.set(false);
}
}
public static void main(String[] args) {
System.out.println("应用启动");
TaskScheduler scheduler = new TaskScheduler();
scheduler.startScheduledTasks();
// 主线程模拟运行10秒
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程结束,所有守护线程终止");
System.exit(0); // 强制退出,确保所有守护线程终止
}
}
配置文件监控守护进程
import java.io.*;
import java.nio.file.*;
import java.util.concurrent.*;
public class ConfigFileWatcherDaemon {
private static class ConfigWatcher {
private final WatchService watchService;
private final Path configDir;
public ConfigWatcher(String dirPath) throws IOException {
configDir = Paths.get(dirPath);
watchService = FileSystems.getDefault().newWatchService();
configDir.register(watchService,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_CREATE);
}
public void startWatching() {
Thread watcherThread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path fileName = ev.context();
System.out.println("[配置守护] 检测到配置变化: " + fileName);
reloadConfig(fileName);
}
boolean valid = key.reset();
if (!valid) {
System.out.println("[配置守护] 目录已删除,停止监控");
break;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
});
watcherThread.setDaemon(true);
watcherThread.setName("配置文件监控守护线程");
watcherThread.start();
System.out.println("开始监控目录: " + configDir);
}
private void reloadConfig(Path fileName) {
try {
Path configFile = configDir.resolve(fileName);
if (Files.exists(configFile)) {
String content = new String(Files.readAllBytes(configFile));
System.out.println("[配置守护] 重新加载配置: " + content);
// 这里执行实际的配置重载逻辑
}
} catch (IOException e) {
System.err.println("[配置守护] 读取配置失败: " + e.getMessage());
}
}
}
public static void main(String[] args) throws IOException {
String configDir = System.getProperty("user.dir") + "/config";
// 确保目录存在
Files.createDirectories(Paths.get(configDir));
ConfigWatcher watcher = new ConfigWatcher(configDir);
watcher.startWatching();
System.out.println("应用运行中,修改 config 目录下的文件测试...");
System.out.println("按 Ctrl+C 退出");
// 保持主线程运行
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
高级:内存监控守护进程
import javax.management.*;
import java.lang.management.*;
import java.util.concurrent.atomic.AtomicLong;
public class MemoryMonitorDaemon {
private static class MemoryMonitor {
private final MemoryMXBean memoryBean;
private final AtomicLong lastLogTime = new AtomicLong(0);
private final double memoryThreshold = 0.8; // 80% 内存使用率
public MemoryMonitor() {
memoryBean = ManagementFactory.getMemoryMXBean();
startMonitoring();
}
private void startMonitoring() {
Thread monitorThread = new Thread(() -> {
System.out.println("内存监控守护线程启动");
while (!Thread.currentThread().isInterrupted()) {
checkMemoryUsage();
try {
Thread.sleep(1000); // 每秒检查一次
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("内存监控中断");
break;
}
}
});
monitorThread.setDaemon(true);
monitorThread.setName("内存监控守护线程");
monitorThread.setPriority(Thread.MIN_PRIORITY); // 低优先级
monitorThread.start();
}
private void checkMemoryUsage() {
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
long usedMemory = heapUsage.getUsed();
long maxMemory = heapUsage.getMax();
if (maxMemory <= 0) {
return;
}
double usageRatio = (double) usedMemory / maxMemory;
long currentTime = System.currentTimeMillis();
// 每隔30秒记录一次
if (currentTime - lastLogTime.get() > 30000) {
System.out.printf("[内存监控] 堆内存使用: %.2f MB / %.2f MB (%.1f%%)%n",
usedMemory / 1024.0 / 1024.0,
maxMemory / 1024.0 / 1024.0,
usageRatio * 100);
lastLogTime.set(currentTime);
}
// 内存使用率超过阀值时告警
if (usageRatio > memoryThreshold) {
System.err.printf("[内存监控警告] 内存使用率过高: %.1f%%%n", usageRatio * 100);
}
}
}
public static void main(String[] args) {
System.out.println("应用开始运行");
// 启动内存监控守护线程
new MemoryMonitor();
// 模拟大量内存分配
System.out.println("开始内存压力测试...");
List<byte[]> memoryList = new ArrayList<>();
try {
for (int i = 0; i < 100; i++) {
memoryList.add(new byte[1024 * 1024]); // 每次分配1MB
Thread.sleep(100);
if (i % 10 == 0) {
System.out.println("已分配 " + (i + 1) + " MB");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("内存压力测试完成,主线程结束");
}
}
完整应用程序示例
import java.util.concurrent.*;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
public class CompleteDaemonApp {
// 业务服务类
static class BusinessService {
public void processRequest(String requestId) {
System.out.println("[业务服务] 处理请求: " + requestId);
try {
Thread.sleep(new Random().nextInt(100));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// 监控服务
static class MonitoringService {
private final BusinessService businessService;
private final AtomicInteger requestCount = new AtomicInteger(0);
public MonitoringService(BusinessService service) {
this.businessService = service;
}
public void startMonitoring() {
// 创建守护线程
Thread monitor = new Thread(() -> {
System.out.println("监控服务启动");
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(5000);
System.out.println("[监控] 5秒内处理的请求数: " + requestCount.getAndSet(0));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
});
monitor.setDaemon(true);
monitor.setName("服务监控");
monitor.start();
}
public void incrementRequestCount() {
requestCount.incrementAndGet();
}
}
// 日志清理服务
static class LogCleanupService {
public void startCleanupScheduler() {
ScheduledExecutorService cleanupScheduler = Executors.newSingleThreadScheduledExecutor(r -> {
Thread t = new Thread(r);
t.setDaemon(true);
t.setName("日志清理");
return t;
});
cleanupScheduler.scheduleAtFixedRate(() -> {
System.out.println("[日志清理] 清理过期日志...");
}, 10, 10, TimeUnit.SECONDS);
}
}
public static void main(String[] args) {
System.out.println("=== 完整守护进程应用示例 ===");
// 初始化服务
BusinessService businessService = new BusinessService();
MonitoringService monitoringService = new MonitoringService(businessService);
LogCleanupService logCleanupService = new LogCleanupService();
// 启动守护服务
monitoringService.startMonitoring();
logCleanupService.startCleanupScheduler();
System.out.println("所有守护服务已启动,开始处理业务请求...");
// 模拟业务请求
for (int i = 0; i < 20; i++) {
final String requestId = "REQ-" + (i + 1);
// 业务请求使用普通线程
Thread worker = new Thread(() -> {
businessService.processRequest(requestId);
monitoringService.incrementRequestCount();
});
worker.setName("业务处理-" + requestId);
worker.start();
}
// 主线程运行一段时间后结束
System.out.println("\n主线程继续运行15秒...");
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\n主线程结束,守护线程随JVM退出");
}
}
关键知识点
创建守护线程的两种方式:
// 方式1: 直接设置
Thread daemon = new Thread(() -> {});
daemon.setDaemon(true);
// 方式2: 使用线程工厂
ThreadFactory daemonFactory = r -> {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
};
守护线程特性:
- 生命周期:所有非守护线程结束时,JVM自动退出
- 优先级:通常设置为较低优先级
- 服务性质:为主线程提供支持服务
- 不可保证:守护线程可能在任何时间被终止
使用建议:
- 用于后台任务(日志、监控、清理等)
- 不要用于需要保存状态的业务逻辑
- 注意线程安全问题(使用线程安全的数据结构)
这些案例涵盖了Java守护进程的常见应用场景,您可以根据实际需求进行调整和使用。