配置接口
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
}