java实现任务调度

本文介绍了如何使用Java实现一个任务调度器,该调度器管理不同优先级的任务队列,保证了优先级高的任务先执行,同一优先级的任务并发执行,不同优先级的任务串行执行。文章详细讲解了从最初的版本到改进版本的设计思路,包括bean初始化、条件设置、任务执行以及异常处理。此外,还提到了在SpringBoot中结合Quartz定时器、Aop和EventBus实现的挑战和解决方案。
摘要由CSDN通过智能技术生成

最近的一个小项目是做一个简单的数据仓库,需要将其他数据库的数据抽取出来,并通过而出抽取成页面需要的数据,以空间换时间的方式,让后端报表查询更快。
因为在抽取的过程中,有一定的先后顺序,需要做一个任务调度器,某一优先级的会先执行,然后会进入下一个优先级的队列任务中。
先定义了一个Map的集合,key是优先级,value是任务的集合,某一个优先级内的任务是并发执行的,而不同优先级是串行执行的,前一个优先级执行完之后,后面的才会执行。

ConcurrentHashMap<Integer/* 优先级. */, List<BaseTask>/* 任务集合. */> tasks = new ConcurrentHashMap<>();

这个调度管理有一个演进的过程,我先说第一个,这个是比较好理解的。
第一个版本:
首先对tasks集合中的key进行一个排序,我定义的是数字越小就有限执行,则进行遍历key值,并取出某个优先级的任务队列,执行任务队列的任务。任务的执行交给线程池去执行,在遍历内部,需要不断的检查这个队列中的任务是否都执行了,没有则一直等待否则进入到下个队列,任务执行的时候可能会抛出异常,但是不管任务是否异常,都将任务状态设置已执行。
下面是其核心代码:

public void run() {
    //对key值进行排序
    Enumeration<Integer> keys = tasks.keys();
    List<Integer> prioritys = new ArrayList<>();
    while (keys.hasMoreElements()) {
      prioritys.add(keys.nextElement());
    }
    Collections.sort(prioritys);//升序
    //对key进行遍历,执行某个某个优先级的任务队列
    for (Integer priority : prioritys) {
      List<BaseTask> taskList = tasks.get(priority);
      if (taskList.isEmpty()) {
        continue;
      }
      logger.info("execute priority {} task ", taskList.get(0).priority);
      for (BaseTask task : taskList) {
        executor.execute(() -> {
          try {
            task.doTask();
          } catch (Exception e) {
            e.printStackTrace();
          }
        });//线程中执行任务
      }
      while (true) {//等待所有线程都执行完成之后执行下一个任务队列
        boolean finish = true;
        for (BaseTask t : taskList) {
          if (!t.finish) {
            finish = false;
          }
        }
        if (finish) {//当前任务都执行完毕
          break;
        }
        Misc.sleep(1000);//Thread.sleep(1000)
      }
      Misc.sleep(1000);
    }
  }

关键代码很好理解,在任务执行之前,需要对所有任务都初始化,初始化的时候给出每个任务的优先级和任务名称,任务抽象类如下:

public abstract class BaseTask {
  public String taskName;//任务名称
  public Integer priority; //优先级
  public boolean finish; //任务完成?
  /**
   * 执行的任务
   */
  public abstract void doTask(Date date) throws Exception;

第一个版本的思路很简单。
第二个版本稍微有一点点复杂。这里主要介绍该版本的内容,后续将代码的链接附上。
程序是由SpringBoot搭建起来的,定时器是Sp

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值