Java守护线程案例如何创建

wen java案例 26

本文目录导读:

Java守护线程案例如何创建

  1. 什么是守护线程
  2. 创建守护线程的基本方法
  3. 实际应用案例
  4. 重要注意事项
  5. 适用场景

我来详细介绍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退出时不会等待守护线程完成的特点。

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