Java守护进程案例

wen java案例 2

本文目录导读:

Java守护进程案例

  1. 基础守护进程案例
  2. 实际业务场景案例
  3. 配置文件监控守护进程
  4. 高级:内存监控守护进程
  5. 完整应用程序示例
  6. 关键知识点

我将为您提供几个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守护进程的常见应用场景,您可以根据实际需求进行调整和使用。

抱歉,评论功能暂时关闭!