java进度信息打印工具ProgressUtil

有时需要批量处理任务,希望打印相关的任务处理信息。写了个工具类。先看效果,后贴代码。

任务进度信息打印效果如下:

业务关键代码:

		ProgressUtil pu = new ProgressUtil("导入数据", list.size());
		for (Record record : list) {
			in.put(1, record.getStr("mkid"));
//			logger.info(record.getStr("mkid") + "开始");
			reportMklbService.callProc(sql, in, out);
//			logger.info(record.getStr("mkid") + "结束");
			pu.finishOne("mkid:"+record.getStr("mkid"));
		}

工具代码ProgressUtil.java:

package com.xpl.util;

import org.apache.log4j.Logger;

/***
 * 进度工具
 * @author xpl
 *
 */
public class ProgressUtil {
	private static final Logger logger = Logger.getLogger("");
	// 工作内容
	String title;
	// 工作量化后总数量
	int total;
	// 已完成的数量
	int finish = 0;
	long startTime;
	long preTime;
	long nextTime;
	//完成一项工作后是否自动休眠
	boolean autoSleep = false;
	//上一次休眠时长
	long preSleepTime;
	//休眠耗时。参考sleep()方法注释
	long [] timeArr = {8000,3000,2000,1000,4000,5000,6000,7000,8000};
	//完成指定数量。参考sleep()方法注释
	int [] countArr = {1,10,20,40,60,80,100};

	public ProgressUtil(String title, int total) {
		this.title = title;
		this.total = total;
		startTime = System.currentTimeMillis();
		preTime = startTime;
	}
	public ProgressUtil(String title, int total, boolean autoSleep) {
		this(title, total);
		this.autoSleep = autoSleep;
	}

	/***
	 * 失败一次,打印信息。
	 */
	public void failureOne(String errorMsg) {
		logger.error(title + " | " + total + " / " + finish  + " | " + "休眠时长:"+ preSleepTime +"|错误信息:"+errorMsg);
	}

	/***
	 * 完成一个任务后,打印信息
	 */
	public void finishOne() {
		finishOne("");
	}

	/***
	 * 完成一个任务后,打印信息
	 * @param taskInfo
	 *            任务信息
	 */
	public void finishOne(String taskInfo) {
		finish++;
		long sleepTime = sleep();
		nextTime = System.currentTimeMillis();
		String str = title + " | 耗时" + getHs(nextTime - preTime) + " | " + total + " / " + finish;
		str += " | 剩余时间:" + getHs(remainingTime());
		str += " | " + taskInfo;
		if(finish == total){
			str += " | 总耗时" + getHs(nextTime - startTime);
		}
		if(sleepTime > 0){
			str += " | 休眠" + getHs(sleepTime);
		}
		logger.info(str);
//		System.out.println(str);
		preTime = nextTime;

	}

	/***
	 * 耗时
	 * @param l
	 * @return
	 */
	public String getHs(long hs) {
		if (hs < 1000) {
			return hs + "毫秒";
		} else if (hs < 1000 * 60) {
			return (hs / 1000) + "秒";
		} else if (hs < 1000 * 60 * 60) {
			return (hs / (1000 * 60)) + "分" + ((hs % (1000 * 60)) / 1000) + "秒";
		} else if (hs < 1000 * 60 * 60 * 60) {
			return (hs / (1000 * 60 * 60)) + "时" + ((hs % (1000 * 60 * 60)) / (1000 * 60)) + "分";
		}
		return hs + "毫秒";
	}

	/***
	 * 自动休眠,autoSleep为true时开启。
	 * 默认:
	 * long [] timeArr = {0,1000,2000,3000,4000,5000,10000};
	 * int [] countArr = {1,3,5,10,20,50,100};
	 * 含义:完成数finish小于等于countArr[i]时,休眠timeArr[i]时长。
	 * finish 大于countArr[countArr.length - 1]时,休眠timeArr[timeArr.length - 1]时长。
	 */
	private long sleep(){
		preSleepTime = 0;
		if(autoSleep && finish < total){
			int i = 0;
			for (; i < countArr.length; i++) {
				if(finish <= countArr[i]){
					break;
				}
			}
			try {
				if(i < timeArr.length){
					preSleepTime = timeArr[i];
				}else{
					preSleepTime = timeArr[timeArr.length - 1];
				}
				Thread.sleep(preSleepTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return preSleepTime;
	}
	/***
	 * 估计剩余时间
	 * 先根据已完成任务数量,求完成一次的平均时间,然后根据待完成任务数估计完成所有任务剩余时间。
	 * @return
	 */
	public long remainingTime() {
		return (nextTime - startTime)/finish * (total - finish);
	}
}

autoSleep 如果为true,则每次完成任务后会自动休眠一段时间。这个主要是网络上批量爬取数据时,避免访问太过频繁被屏蔽时使用。

failureOne 一般在业务代码中try catch中使用,抛出异常或者有任务执行失败的标志时调用。可以清楚的知道哪个任务出错了。

例子:

/***
	 * 爬取并保持章节内容
	 * @param rm
	 * @param list
	 */
	public void crawlAndSaveContent(ResponseMap rm, List<Mulu> list) {
		int size = list.size();
		ProgressUtil pu = new ProgressUtil("更新章节内容", size, true);
		for (Mulu mulu : list) {
			try{
				muluService.updateContent(rm, mulu);
			} catch (Exception e) {
				e.printStackTrace();
				pu.failureOne(e.getMessage()+"|"+mulu.getUrl());
			}
			pu.finishOne(mulu.getUrl());
			size--;
		}
	}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值