文章目录

  • 状态可变数据
  • while进行控制
  • 状态不变数据
  • while(true) 或者 while(flag) 或者 do while
  • while(true)写法
  • do while写法
  • 总结
  • 无限循环的危害



定时任务查出的条数可能不同,如何进行控制呢。

数据主要分为两类。
一是状态变化数据。
二是状态不变数据。

状态可变数据

每循环一次之后状态会变化,或者次数+1,或者其他标记值改变。

while进行控制

while (true){
    List<Entity> list= service.selectList();
    log.info("本次查出的数据:{}", JSONObject.toJSONString(list));
    if(list==null || list.size()==0){
        log.info("未查出数据结束任务");
        return ;
    }
    for(Entity item:list){
        // 业务逻辑
    }
}

这段代码通常来说没问题,但是也有注意点。
那就是循环的数据要保证状态变更。
即运行过一次后,一定要确保改变信息使下一次相同条件无法再查到。
否则就会出现无限循环的问题。

例如,这次查到了,判断通过后,修改状态。但是因为判断条件始终不通过,状态一直没修改,那么这个while永远跑不完了,下次定时任务也永远无法执行。

另外,最好可以加上个计数器,记录循环的次数,可以做到心里有数。

状态不变数据

状态不进行任何改变,例如获取某个时间段的数据,进入到备份表。

因为没有状态改变,所以必须让每次的数据不同,否则就无限循环了。

可以pageNo的改变,超过pages就结束。 需要主意的是,一定要加分页信息。

while(true) 或者 while(flag) 或者 do while

其实都没太大区别。

while(true)写法

这种写法,退出条件在代码中定义即可。
代码:

// 设置页码数
int pageNo = 0;
// 设置每页的数量
int pageSize = 100;
while(true){
    pageNo++;
    queryParam.setPageNo(pageNo);
    queryParam.setPageSize(pageSize);

    logger.info("循环次数:{}",pageNo);
    PageHelper.startPage(queryParam.getPageNo(), queryParam.getPageSize());
    List<User> queryResult = mapper.selectList(queryParam);
    PageInfo<User> pageInfo = new PageInfo<>(queryResult);
    logger.info("pageInfo简化版:{}",pageInfo.toStringSimple());
    int pages = pageInfo.getPages();
    //            100条 1页
    //            101条 2页
    if(pageNo>pages){ // 如果页码>总页数 结束循环
    break;
    }
    // 业务代码
}

pageInfo.toStringSimple()是为了打印出pageInfo除了list的信息,因为list信息比较多,不推荐打印,这里重写下PageInfo类即可。

do while写法

肯定也是可以的,pageNo和pages开始没有,给一个初始值,后面再赋值即可。

总结

总的来说,就是一定要避免无限循环,可以通过页码比对,也可以通过条数比对。
如果条数不多,懒一点可以不用循环,只查一次,条数大些,例如10000条,基本也够用。

无限循环的危害

这样任务永远跑不玩,不但对性能有压力,后续的任务也不会再跑了,很坑。