定时任务调度

定时任务调度

最近拿到一个需求,需要在前端配置一些任务,在固定的时间去执行,于是想到可以使用这个方法进行处理,就浅记 一下这个用法

1、配置一个任务调度类,这个类可以直接使用无需修改

/**
 * 定时任务调度类
 */
@Component
public class TaskConfig implements SchedulingConfigurer {

	private volatile ScheduledTaskRegistrar registrar;

	private final ConcurrentHashMap<String, ScheduledFuture<?>> scheduledFutures = new ConcurrentHashMap<>();
	private final ConcurrentHashMap<String, CronTask> cronTasks = new ConcurrentHashMap<>();


	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		//设置10个线程,同时并发执行任务
		ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
		taskScheduler.setPoolSize(10);
		taskScheduler.initialize();
		taskRegistrar.setScheduler(taskScheduler);
		this.registrar = taskRegistrar;
	}

	/**
	 * 修改 cron 需要 调用该方法
	 */
	public void refresh(List<TaskEntity> tasks, Function<TaskEntity,CronTask> fun){
		//取消已经删除的策略任务
		Set<String> sids = scheduledFutures.keySet();
		for (String sid : sids) {
			if(exists(tasks, sid)){
				scheduledFutures.get(sid).cancel(true);
			}
		}
		for (TaskEntity taskEntity : tasks) {
			String expression = taskEntity.getExpression();
			//计划任务表达式为空则跳过
			if(ValidateUtil.isEmpty(expression)){
				continue;
			}
			//计划任务已存在并且表达式未发生变化则跳过
			if (scheduledFutures.containsKey(taskEntity.getTaskId())
					&& cronTasks.get(taskEntity.getTaskId()).getExpression().equals(expression)) {
				continue;
			}
			//业务逻辑处理
			CronTask task = fun.apply(taskEntity);
			//执行业务
			ScheduledFuture<?> future = Objects.requireNonNull(Objects.requireNonNull(registrar.getScheduler())).schedule(task.getRunnable(), task.getTrigger());
			cronTasks.put(taskEntity.getTaskId(), task);
			assert future != null;
			scheduledFutures.put(taskEntity.getTaskId(), future);
		}
	}

	/**
	 * 停止 cron 运行
	 */
	public void stop(List<TaskEntity> tasks){
		tasks.forEach(item->{
			if (scheduledFutures.containsKey(item.getTaskId())) {
				// mayInterruptIfRunning设成false话,不允许在线程运行时中断,设成true的话就允许。
				scheduledFutures.get(item.getTaskId()).cancel(true);
				scheduledFutures.remove(item.getTaskId());
			}
		});
	}

	private boolean exists(List<TaskEntity> tasks, String tid){
		for(TaskEntity TaskEntity:tasks){
			if(TaskEntity.getTaskId().equals(tid)){
				return true;
			}
		}
		return false;
	}

	@PreDestroy
	public void destroy() {
		this.registrar.destroy();
	}

}

2、TaskEntity可以根据你自己的需求进行设置,以下是一个简易的模板

/**
 * 定时任务执行类
 */
public class TaskEntity {
	/**
	 * 任务id
	 */
	private String taskId;
	/**
	 * 任务说明
	 */
	private String desc;
	/**
	 * cron 表达式
	 */
	private String expression;


	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	public String getExpression() {
		return expression;
	}

	public void setExpression(String expression) {
		this.expression = expression;
	}

	public TaskEntity() {
	}

	public TaskEntity(String taskId, String desc, String expression) {
		this.taskId = taskId;
		this.desc = desc;
		this.expression = expression;
	}

	@Override
	public String toString() {
		return "TaskEntity{" +
				"taskId='" + taskId + '\'' +
				", desc='" + desc + '\'' +
				", expression='" + expression + '\'' +
				'}';
	}
}


3、具体的业务处理类,根据需求修改

/**
 * 定时任务业务处理类
 */
public class TaskHandler implements Function<TaskEntity, CronTask> {
   @Override
   public CronTask apply(TaskEntity taskEntity) {
      return new CronTask(() -> {
         //todo-具体的业务代码处理
         System.err.println(Thread.currentThread() + "===" + taskEntity.toString());
      }, taskEntity.getExpression());
   }
}

4、方法调用

List<TaskEntity> list = new ArrayList<>();
list.add(new TaskEntity("taskid", "描述", "0 0/2 * * * ?"));
taskConfig.refresh(list, new TaskHandler());

支持动态添加修改任务,比较高效

测试结果如下:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值