MST

星途 面试题库

面试题:Java定时及周期执行线程池任务调度之动态调整

在使用ScheduledThreadPoolExecutor实现定时任务的基础上,假设任务执行的周期需要根据外部配置动态调整(例如从配置文件读取新的周期时间),请描述如何优雅地实现这一功能,并给出关键代码片段。
45.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 实现思路
    • 使用ScheduledThreadPoolExecutor创建定时任务。
    • 建立一个机制来监听配置文件的变化,当配置文件中周期时间发生变化时,取消当前正在执行的定时任务,并根据新的周期时间重新创建定时任务。
  2. 关键代码片段
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class DynamicScheduledTask {
    private ScheduledExecutorService executorService;
    private ScheduledFuture<?> future;
    private long initialPeriod = 5; // 初始周期时间,单位秒
    private long period;

    public DynamicScheduledTask() {
        this.period = initialPeriod;
        executorService = Executors.newScheduledThreadPool(1);
        startTask();
    }

    private void startTask() {
        future = executorService.scheduleAtFixedRate(() -> {
            // 定时任务要执行的内容
            System.out.println("执行定时任务");
        }, 0, period, TimeUnit.SECONDS);
    }

    public void updatePeriod(long newPeriod) {
        this.period = newPeriod;
        if (future != null &&!future.isCancelled()) {
            future.cancel(true);
        }
        startTask();
    }

    public void shutdown() {
        if (executorService != null) {
            executorService.shutdown();
        }
    }

    public static void main(String[] args) {
        DynamicScheduledTask task = new DynamicScheduledTask();
        try {
            // 模拟外部配置修改,这里延迟10秒后修改周期为10秒
            TimeUnit.SECONDS.sleep(10);
            task.updatePeriod(10);
            // 主线程休眠30秒后关闭任务
            TimeUnit.SECONDS.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            task.shutdown();
        }
    }
}

在上述代码中:

  • DynamicScheduledTask类负责管理定时任务。
  • startTask方法创建并启动定时任务。
  • updatePeriod方法用于更新任务执行周期,它先取消当前任务,再根据新的周期重新启动任务。
  • main方法模拟了外部配置修改和任务的关闭过程。实际应用中,监听配置文件变化可使用如java.nio.file.WatchService等相关技术来实现。