定時任務幫助類
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: 時間單位; ScheduledFuture<?> 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: 時間單位; ScheduledFuture<?> task = threadPoolExecutor.schedule(job, initialDelay, TimeUnit.SECONDS); scheduledFutureMap.put(key, task); } } /** * 執行定時任務(指定執行次數) * @param key 任務的唯一標識,用于避免重復添加相同任務。 * @param job 需要執行的任務,實現了Runnable接口。 * @param initialDelay 任務首次執行的延遲時間(秒)。 * @param period 任務執行的周期時間(秒)。 * @param times 任務執行的次數。 * @param taskConsuming 單次任務執行的大概耗時(秒數)。 * */ public static void doJobSomeTimes(String key, Runnable job, long initialDelay, long period, int times,long taskConsuming) { for (int k = 0; k < times; k++) { String idxKey = key + "_" + (k + 1); getThreadPoolExecutorInstance(); // 參數1: task任務; // 參數2: 首次執行任務的延遲時間; // 參數3: 時間單位; if (k == 0) { ScheduledFuture<?> task = threadPoolExecutor.schedule(job, initialDelay, TimeUnit.SECONDS); scheduledFutureMap.put(idxKey, task); } else { //下一次執行任務需要延遲多少時間 long nextJobDelay = initialDelay + ((period + taskConsuming) * k); ScheduledFuture<?> task = threadPoolExecutor.schedule(job, nextJobDelay, TimeUnit.SECONDS); scheduledFutureMap.put(idxKey, task); } } } /** * 停止定時任務(非強制,如果正在執行,會等待執行完成后再關閉。) */ public static void removeJob(String key) { if (scheduledFutureMap.containsKey(key)) { ScheduledFuture<?> task = scheduledFutureMap.get(key); if (task != null) { task.cancel(false); } scheduledFutureMap.remove(key); } } /** * 停止定時任務(非強制,如果正在執行,會等待執行完成后再關閉。) */ public static void removeTimesJob(String key, int times) { for (int k = 0; k < times; k++) { String idxKey = key + "_" + (k + 1); if (scheduledFutureMap.containsKey(idxKey)) { ScheduledFuture<?> task = scheduledFutureMap.get(idxKey); if (task != null) { task.cancel(false); } scheduledFutureMap.remove(idxKey); } } } /** * 停止全部任務(非強制,如果正在執行,會等待執行完成后再關閉。) */ public static void removeAllJob() { if (threadPoolExecutor != null) { threadPoolExecutor.shutdown(); } scheduledFutureMap.clear(); } /** * 是否已經存在job * */ public static boolean existsJob(String key) { return scheduledFutureMap.containsKey(key); } }
測試
//設置定時任務 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);
浙公網安備 33010602011771號