定时任务帮助类
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);

 

posted on 2023-08-10 09:24  邢帅杰  阅读(56)  评论(0编辑  收藏  举报