定时任务帮助类
测试
package com.xcg.webapp.common; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; /**final类不可以继承*/ public final class ScheduledThreadUtil { /** * 不可以创建新对象 */ private ScheduledThreadUtil() { } /** * 存储定时任务 * */ private static final Map<String, ScheduledFuture> scheduledFutureMap = new HashMap<>(); /** * 可调度线程池 * */ private static ScheduledThreadPoolExecutor threadPoolExecutor = null; /** * 保持线程池单实例 * */ public static ScheduledThreadPoolExecutor getThreadPoolExecutorInstance() { if (threadPoolExecutor == null) { synchronized (ScheduledThreadUtil.class) { if (threadPoolExecutor == null) { threadPoolExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(16); } } } return threadPoolExecutor; } /** * 执行定时任务 * @param key 任务的唯一标识,用于避免重复添加相同任务。 * @param job 需要执行的任务,实现了Runnable接口。 * @param initialDelay 任务首次执行的延迟时间(秒)。 * @param period 任务执行的周期时间(秒)。 */ public static void doJob(String key, Runnable job, long initialDelay, long period) { //避免重复的任务 if (!scheduledFutureMap.containsKey(key)) { getThreadPoolExecutorInstance(); // 参数1: task任务; // 参数2: 首次执行任务的延迟时间; // 参数3: 周期性执行的时间; // 参数4: 时间单位; var task = threadPoolExecutor.scheduleAtFixedRate(job, initialDelay, period, TimeUnit.SECONDS); scheduledFutureMap.put(key, task); } } /** * 执行定时任务(只执行一次) * @param key 任务的唯一标识,用于避免重复添加相同任务。 * @param job 需要执行的任务,实现了Runnable接口。 * @param initialDelay 任务首次执行的延迟时间(秒)。 * */ public static void doJobOnce(String key, Runnable job, long initialDelay) { //避免重复的任务 if (!scheduledFutureMap.containsKey(key)) { getThreadPoolExecutorInstance(); // 参数1: task任务; // 参数2: 首次执行任务的延迟时间; // 参数3: 时间单位; var task = threadPoolExecutor.schedule(job, initialDelay, TimeUnit.SECONDS); scheduledFutureMap.put(key, task); } } /** * 停止定时任务(非强制,如果正在执行,会等待执行完成后再关闭。) */ public static void removeJob(String key) { if (scheduledFutureMap.containsKey(key)) { var task = scheduledFutureMap.get(key); task.cancel(false); } } /** * 停止全部任务(非强制,如果正在执行,会等待执行完成后再关闭。) */ public static void removeAllJob() { if (threadPoolExecutor != null) { threadPoolExecutor.shutdown(); } } }
//设置定时任务 ScheduledThreadUtil.doJob("job1", new Runnable() { @Override public void run() { System.out.println("定时任务1,每1秒执行一次:" + DateUtil.format(new Date(), DateUtil.DF_YYYY_MM_DDHHMMSS)); } }, 1, 1); ScheduledThreadUtil.doJob("job2", new Runnable() { @Override public void run() { System.out.println("定时任务2,每5秒执行一次:" + DateUtil.format(new Date(), DateUtil.DF_YYYY_MM_DDHHMMSS)); } }, 1, 5); Thread.sleep(20000); ScheduledThreadUtil.removeJob("job1"); Thread.sleep(20000); ScheduledThreadUtil.removeAllJob();
每天11点执行一次
//任务周期,每天执行一次任务。 long periodSec = TimeUnit.DAYS.toSeconds(1); //当前时间 Date nowDate = new Date(); //当前时间戳 long nowTime = nowDate.getTime() / 1000L; //目标时间 String ymd = DateUtil.format(nowDate, DateUtil.DF_YYYY_MM_DD); Date targetDate = DateUtil.parse(ymd + " 11:38:00", DateUtil.DF_YYYY_MM_DDHHMMSS); //如果当前时间大于11点,则目标时间为明天的11点。 if (nowDate.after(targetDate)) { //加一天 targetDate = DateUtil.add(targetDate, Calendar.DAY_OF_MONTH, 1); } long nowTime11 = targetDate.getTime() / 1000L; //首次延迟时间,单位为秒。 long initialDelay = nowTime11 - nowTime; ScheduledThreadUtil.doJob("job3", new Runnable() { @Override public void run() { System.out.println("定时任务3,每天的11点执行一次:" + DateUtil.format(new Date(), DateUtil.DF_YYYY_MM_DDHHMMSS)); } }, initialDelay, periodSec);