文章目录
- 状态可变数据
- 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条,基本也够用。
无限循环的危害
这样任务永远跑不玩,不但对性能有压力,后续的任务也不会再跑了,很坑。