Loading

定时任务

配置接口

package test;

import java.util.concurrent.TimeUnit;

public interface IScheduledCfg {

    String getName();

    int getCount();

    long getInitialDelay();

    long getCycleTime();

    TimeUnit getTimeUnit();
}

配置类

package test;

import lombok.EqualsAndHashCode;
import lombok.Getter;

import java.util.concurrent.TimeUnit;

@Getter
@EqualsAndHashCode(of = "name")
public class NewScheduledCfg implements IScheduledCfg {
    /**
     * 线程名
     */
    private String name;
    /**
     * 线程数,默认都是1
     */
    private int count;
    /**
     * 延时/ms
     */
    private long initialDelay;
    /**
     * 周期时间/ms
     */
    private long cycleTime;
    /**
     * 时间单位
     */
    private TimeUnit timeUnit;

    public NewScheduledCfg(String name, int count, long initialDelay, long cycleTime, TimeUnit timeUnit) {
        this.name = name;
        this.count = count;
        this.initialDelay = initialDelay;
        this.cycleTime = cycleTime;
        this.timeUnit = timeUnit;
    }
}

可以提前预配置好的枚举类

@Getter
public enum ScheduledCfg implements IScheduledCfg {
    WORK_ONE("work-1", 1, 0, 2, TimeUnit.SECONDS),
    WORK_TWO("work-2", 1, 0, 2, TimeUnit.SECONDS);
	
    /**
     * 线程名
     */
    private String name;
    /**
     * 线程数,默认都是1
     */
    private int count;
    /**
     * 延时/ms
     */
    private long initialDelay;
    /**
     * 周期时间/ms
     */
    private long cycleTime;
    /**
     * 时间单位
     */
    private TimeUnit timeUnit;

    ScheduledCfg(String name, int count, long initialDelay, long cycleTime, TimeUnit timeUnit) {
        this.name = name;
        this.count = count;
        this.initialDelay = initialDelay;
        this.cycleTime = cycleTime;
        this.timeUnit = timeUnit;
    }
}

定时循环任务

package test;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ScheduledTask {

    private IScheduledCfg scheduledCfg;

    private Runnable task;

    private long cycleTime;

    private ScheduledThreadPoolExecutor executor;

    public ScheduledTask(IScheduledCfg scheduledCfg, Runnable task) {
        this.scheduledCfg = scheduledCfg;
        this.task = task;
    }

    public void start() {
        start(cycleTime);
    }

    public void start(long time) {
        try {
            if (executor == null || executor.isShutdown()) {
                executor = new ScheduledThreadPoolExecutor(scheduledCfg.getCount(),
                        new ThreadFactoryBuilder().setPriority(Thread.MAX_PRIORITY)
                                .setNameFormat(scheduledCfg.getName()).build());
            }
            cycleTime = time <= 0 ? scheduledCfg.getCycleTime() : time;
            executor.scheduleWithFixedDelay(
                    task, scheduledCfg.getInitialDelay(), cycleTime, scheduledCfg.getTimeUnit());
        } catch (Exception e) {
            // 这里日志打印
        }
    }

    public void stop() {
        try {
            executor.shutdown();
            executor.awaitTermination(3, TimeUnit.SECONDS);
        } catch (Exception e) {
             // 这里日志打印
        } finally {
            try {
                executor.shutdownNow();
            } catch (Exception e) {
                 // 这里日志打印
            }
        }
    }
}

定时触发的一次性任务

package test;

import lombok.EqualsAndHashCode;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 *  定时触发的任务,一次性任务。需要循环的请使用 ScheduledTask.java
 */
@EqualsAndHashCode(callSuper = true, of = "name")
public class ScheduledTimerTask extends TimerTask {

    /**
     * 任务名
     */
    private String name;
    /**
     * 定时器
     */
    private Timer timer;
    /**
     * 任务
     */
    private Runnable runnable;
    /**
     * 触发时间
     */
    private Date date;

    public ScheduledTimerTask(String name, Runnable runnable, Date date) {
        this.name = name;
        this.timer = new Timer(name);
        this.runnable = runnable;
        this.date = date;
    }

    /**
     * @return false,说明该定时任务已经不需要再触发了,则可以移除了
     */
    public boolean start() {
        if (date.getTime() > System.currentTimeMillis()) {
            this.timer.schedule(this, date);
            return true;
        }
        return false;
    }

    public void stop() {
        this.timer.cancel();
    }

    @Override
    public void run() {
        runnable.run();
    }
}

定时线程池

package test;

import test.ScheduledTimerTask;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 定时器、循环线程
 */
@SuppressWarnings("squid:S1181")
public class ScheduledThreadPool {

    private static ScheduledThreadPool instance = new ScheduledThreadPool();
    /**
     * 定时器
     */
    private static Map<String, ScheduledTimerTask> timerTasks = new ConcurrentHashMap<>();
    /**
     * 循环线程
     */
    private static Map<IScheduledCfg, ScheduledTask> scheduledTaskMap = new ConcurrentHashMap<>();

    private ScheduledThreadPool() {

    }

    public static ScheduledThreadPool getIns() {
        return instance;
    }

    public static void addOneScheduledTask(IScheduledCfg cfg, Runnable runnable) {
        addOneScheduledTask(cfg, runnable, cfg.getCycleTime());
    }

    public static void addOneScheduledTask(IScheduledCfg cfg, Runnable runnable, long time) {
        try {
            removeOneScheduledTask(cfg);

            ScheduledTask scheduledTask = new ScheduledTask(cfg, runnable);
            scheduledTaskMap.put(cfg, scheduledTask);
            scheduledTask.start(time);
        } catch (Throwable e) {
            // 日志打印
        }
    }

    public static void removeOneScheduledTask(IScheduledCfg cfg) {
        try {
            ScheduledTask scheduledTask = scheduledTaskMap.remove(cfg);
            if (scheduledTask != null) {
                scheduledTask.stop();
            }
        } catch (Throwable e) {
            // 日志打印
        }
    }

    public static void addOneTimeTask(String name, Runnable runnable, Date date) {
        try {
            removeOneTimeTask(name);

            ScheduledTimerTask scheduledTimerTask = new ScheduledTimerTask(name, runnable, date);
            timerTasks.put(name, scheduledTimerTask);
            scheduledTimerTask.start();
        } catch (Throwable e) {
            // 日志打印
        }
    }

    public static void removeOneTimeTask(String name) {
        try {
            ScheduledTimerTask scheduledTimerTask = timerTasks.remove(name);
            if (scheduledTimerTask != null) {
                scheduledTimerTask.stop();
            }
        } catch (Throwable e) {
            // 日志打印
        }
    }

    /**
     * 定时器、循环线程重启
     */
    public static void activeAll() {
        Map<String, ScheduledTimerTask> iteratorMap = new ConcurrentHashMap<>(timerTasks);
        for (Map.Entry<String, ScheduledTimerTask> next : iteratorMap.entrySet()) {
            if (!next.getValue().start()) {
                timerTasks.remove(next.getKey());
            }
        }
        scheduledTaskMap.values().forEach(ScheduledTask::start);
    }

    /**
     * 定时器、循环线程终止
     */
    public static void stopAll() {
        timerTasks.values().forEach(ScheduledTimerTask::stop);
        scheduledTaskMap.values().forEach(ScheduledTask::stop);
    }
}

使用示例

    public static void main(String[] args){
        // 新建配置类,创建定时任务
        String taskId = "test";
        Long initalDelay = 10L;
        Long interval = 100L;
        int threadCount = 1;
        scheduledCfg = new NewScheduledCfg(taskId, threadCount, initialDelay, interval, TimeUnit.MILLISECONDS);
        ScheduledThreadPool.addOneScheduledTask(scheduledCfg, this::work);
		
        //使用配置枚举类,创建定时任务
        ScheduledThreadPool.addOneScheduledTask(ScheduledCfg.WORK_ONE, () -> {
		//TODO
       })
    }

    private void work(){
        // TODO
    }
posted @ 2024-02-29 10:42  星流残阳  阅读(20)  评论(0编辑  收藏  举报