动态定时任务
动态定时任务,可以根据cron来动态改变定时任务
package com.smxr.utils.task;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @Author lzy
* @Date 2021.06.21 17:10
* @PC smxr
* 执行线程的实现类
*/
public class TaskScheduledExecute implements Runnable{
private static final Logger logger= LoggerFactory.getLogger(TaskScheduledExecute.class);
//执行设备或业务,具体的有意义的参数
private String ivm;
private String cron;//执行cron
private String dateTime;//执行任务创建时间
private TaskScheduledExecute() {
}
public TaskScheduledExecute(String ivm, String cron) {
this.ivm = ivm;
this.cron = cron;
this.dateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
public static Logger getLogger() {
return logger;
}
public String getIvm() {
return ivm;
}
public String getCron() {
return cron;
}
return dateTime;
}
@Override
public String toString() {
return "TaskScheduledExecute{" +
"ivm='" + ivm + '\'' +
", cron='" + cron + '\'' +
", dateTime='" + dateTime + '\'' +
'}';
}
@Override
public void run() {
try {
logger.info("测试 "+this.ivm+" 定时任务在运行中"+getCron());
} catch (Exception e) {
// logger.info(this.getIvm()+" 运行异常..."+e.toString());
logger.info(this.getIvm()+" 运行异常...");
e.printStackTrace();
}
}
}
package com.smxr.utils.task;
import com.smxr.controller.AccountController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* @Author lzy
* @Date 2021.06.21 16:35
* @PC smxr
* 线程池工具类
*/
@Component
public class TaskScheduled {
private static final Logger logger= LoggerFactory.getLogger(TaskScheduled.class);
@Autowired //线程池
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
//定时任务回调
private static Map<String,ScheduledFuture<?>> futureMap=new ConcurrentHashMap<>();
//定时任务信息
public static Map<String,TaskScheduledExecute> futureHashMap=new HashMap<>();
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){//初始化线程池
logger.info("threadPoolTaskScheduler ---- info loading...");
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(2);//设置线程数量
/**设置为false,关闭线程池中的任务时,直接执行shutdownNow() 延时关闭 开启*/
//threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
//threadPoolTaskScheduler.setAwaitTerminationSeconds(60);//演示挂壁的时间为60s
threadPoolTaskScheduler.initialize();//实例化线程
//threadPoolTaskScheduler.setThreadNamePrefix("");//设置线程名字的前缀
//return new ThreadPoolTaskScheduler();//默认只有一个线程
return threadPoolTaskScheduler;
}
//启动定时任务
public boolean start(TaskScheduledExecute taskScheduledExecute,String cron){
if (futureMap.get(taskScheduledExecute.getIvm())!=null){
return false;
}
try {
ScheduledFuture<?> schedule = threadPoolTaskScheduler.schedule(taskScheduledExecute, new CronTrigger(cron));
futureMap.put(taskScheduledExecute.getIvm(),schedule);
futureHashMap.put(taskScheduledExecute.getIvm(),taskScheduledExecute);
logger.info(taskScheduledExecute.getIvm()+"...已经启动");
//logger.info(schedule.toString());
//打印如下
//DelegatingErrorHandlingRunnable for TaskScheduledExecute
// {ivm='CB0001A9991E', cron='0 */1 * * * ?', executeNumber=5, executeTimeS=1000, dateTime='2021-06-22 12:06:45'}
}catch (Exception e){
logger.error(taskScheduledExecute.getIvm()+" 执行异常: "+e.toString());
return false;
}
return true;
}
//停止定时任务 ivm 设备id
public boolean stop(String ivm){
try {
ScheduledFuture<?> scheduledFuture = futureMap.get(ivm);
if(futureMap.get(ivm)==null){
return false;
}
if (scheduledFuture==null){
logger.info("定时任务已经不在调度中,无法停止!"+ivm);
}else {
//任务是否已经注销
// final boolean cancelleds = scheduledFuture.isCancelled();
// logger.info("stop...》cancelled: "+cancelleds);//false
// // 是否完成,线程的run()是否执行完毕,
// final boolean dones = scheduledFuture.isDone();
// logger.info("stop...》done: "+dones);// true
//取消任务
scheduledFuture.cancel(true);
//scheduledFuture 无实现类,所用的是任务启动时所返回的实现类
//1.getDelay(入参:返回的时间格式) 剩余延迟时间;零或负值指示延迟时间已经用尽
// long delay = scheduledFuture.getDelay(TimeUnit.SECONDS);
//logger.info("stop...》delay: "+delay);//43s
//2.停止此任务运行,如果该任务没有启动,就永远不会在启动,如果该任务已经启动,那么由入参来确定是否停止该任务
//如果执行该任务的线程应该被中断,则为true;否则,正在进行的任务将被允许完成
// boolean cancel = scheduledFuture.cancel(true);
// logger.info("stop...》cancel: "+cancel);// false (run中只有一个打印已经完成,所以为false)
//任务是否已经注销
// final boolean cancelled = scheduledFuture.isCancelled();
// logger.info("stop...》cancelled: "+cancelled);//true
是否完成,线程的run()是否执行完毕,
// final boolean done = scheduledFuture.isDone();
// logger.info("stop...》done: "+done);// true
futureMap.remove(ivm);
futureHashMap.remove(ivm);
logger.info(ivm+"...已经停止");
logger.info(scheduledFuture.toString());
}
}catch (Exception e){
logger.error(ivm+" 执行异常: "+e.toString());
return false;
}
return true;
}
public boolean start(TaskScheduledExecute taskScheduledExecute){
final String ivm = taskScheduledExecute.getIvm();
if (futureMap.get(ivm)==null){
logger.info("该设备没有定时任务...creating");
return this.start(taskScheduledExecute, taskScheduledExecute.getCron());
}else {
if (futureHashMap.get(ivm).getCron().equals(taskScheduledExecute.getCron())){
return true;
}
this.stop(ivm);
logger.info("该设备已有定时任务...clearing");
return this.start(taskScheduledExecute, taskScheduledExecute.getCron());
}
}
}
对外接口
@CountTimeSecond//此注解一个简单的AOP切面统计接口耗时的
@RequestMapping("/taskStart")
public void taskScheduledStart(String ivm,String cron){//测试定时任务接口启动
logger.info("taskStart...");
// String cron="0 * * * * ?";
// boolean start = taskScheduled.start(new TaskScheduledExecute("CB0001A9991E", cronStr, 5, 1000), cron);
TaskScheduledExecute cb0001A9991E = new TaskScheduledExecute(ivm, cron);
boolean start = taskScheduled.start(123456);
if (start)
logger.info("result...start:"+start);
else
logger.info("result...start:"+start+" 该定时任务已存在");
}
@CountTimeSecond
@RequestMapping("/taskStop")
public void taskScheduledStop(String ivm){//测试定时任务结束
logger.info("taskStop...");
boolean stop = taskScheduled.stop(ivm);
logger.info("result...stop:"+stop);
}
@CountTimeSecond
@RequestMapping("/taskStart2")
public void taskScheduledStart2(){
logger.info("taskStart...");
String cron="0 */1 * * * ?";
boolean start = taskScheduled.start(new TaskScheduledExecute("CB0001A9991F", cron), cron);
if (start)
logger.info("result...start:"+start);
else
logger.info("result...start:"+start+" 该定时任务已存在");
}
@CountTimeSecond
@RequestMapping("/taskStop2")
public void taskScheduledStop2(){
logger.info("taskStop...");
boolean stop = taskScheduled.stop("123456");
logger.info("result...stop:"+stop);
}