Java实现在夜间运行任务

白天时服务器一般收到用户的请求较多,执行比较多的任务。晚上收到用户的请求少,压力小,可以在夜间执行一些耗时的操作,如生成报表。本文将介绍,在多公司,一个公司对应一个数据库的情景下,如何在夜间执行任务,生成各个公司的报表。本文将介绍以下内容:“创建运行报表的相关类”、“报表类的执行逻辑”、“启动所有报表线程”。1、创建运行报表的相关类。TaskThread继承于Thread,是一个线程类。所有...
摘要由CSDN通过智能技术生成

白天时服务器一般收到用户的请求较多,执行比较多的任务。晚上收到用户的请求少,压力小,可以在夜间执行一些耗时的操作,如生成报表。本文将介绍,在多公司,一个公司对应一个数据库的情景下,如何在夜间执行任务,生成各个公司的报表。本文将介绍以下内容:“创建运行报表的相关类”、“报表类的执行逻辑”、“启动所有报表线程”。

1、创建运行报表的相关类。

TaskThread继承于Thread,是一个线程类。所有类型的报表继承于TaskThread类,TaskThread存放公共属性和方法:

@Component("taskThread")
@Scope("prototype")
public class TaskThread extends Thread 
TaskThread的run方法
	@Override
	public void run() {
		while (atomicInteger.get() != SIGNAL_ThreadExit) {
			doTask();
			try {
				if (isMockingMVC) {
					timeSpanToCheckTaskStartTime = 50; // 在测试环境下,检查频繁一点,以缩短报表测试的运行时间
				} else {
					timeSpanToCheckTaskStartTime = 10000; // 检查疏一点,以免占用太多CPU时间
				}
				Thread.sleep(timeSpanToCheckTaskStartTime);  
			} catch (InterruptedException e) {
				logger.error("夜间检查任务【" + name + "】定时任务线程异常" + e.getMessage());
				return;
			}
		}
	}

Run方法调用了doTask方法,

doTask方法执行的逻辑:

(1)遍历所有公司;

(2)判断是否已经到了执行该任务的时间dateToRunReport;

(3)如果到了执行任务的时间,那么设置下一次执行任务的时间是24小时候dateToRunNextTime;

(4)开始执行doTaskForEveryCompany:

protected void doTask() {
		List<BaseModel> list = CacheManager.getCache(BaseAction.DBName_Public, EnumCacheType.ECT_Company).readN(false, false);
		for (BaseModel bm : list) {
			Company company = (Company) bm;
			if (!company.getDbName().equals(BaseAction.DBName_Public)) {// 公共DB没有夜间任务
				if (company.getIncumbent() == EnumCompanyCreationStatus.ECCS_Incumbent.getIndex() && company.getStatus() == EnumCompanyCreationStatus.ECCS_Incumbent.getIndex()) {// 表示创建公司时是否已经创建完成
					Date dateToRunReport = (getReportDateForTest() == null ? new Date() : getReportDateForTest());
					if (mapDatetimeForNextRun.get(company.getDbName()) == null) {
						mapDatetimeForNextRun.put(company.getDbName(), getStartDatetime(company.getDbName()));// 有的公司是后来创建的
					}
					// 如果时间已经超过本夜间任务设定的运行时间,则设置此时间为24小时后再跑一次,然后才跑夜间任务。子类中,可以自定义夜间任务跑或不跑、如何跑。
					if (DatetimeUtil.isAfterDate(dateToRunReport, mapDatetimeForNextRun.get(company.getDbName()), 0) || canRunOnceForTest()) {
						logger.info("定时任务执行时间段已到,开始运行任务, \t本线程hashcode=" + this.hashCode());
						Date dateToRunNextTime = mapDatetimeForNextRun.get(company.getDbName());
						dateToRunNextTime = DatetimeUtil.getDate(dateToRunNextTime, 24 * 3600);
						mapDatetimeForNextRun.put(company.getDbName(), dateToRunNextTime);
						doTaskForEveryCompany(company);
						taskStatusForTest.incrementAndGet();
					}
				}
			}
		}
	}

2、报表类的执行逻辑。

以销售商品分类占比报表为例,介绍报表的生成过程。

类名为RetailTradeDailyReportByCategoryParentTaskThread,继承了TaskThread:

@Component("retailTradeDailyReportByCategoryParentTaskThread")
@Scope("prototype")
public class RetailTradeDailyReportByCategoryParentTaskThread extends TaskThread

因为它是TaskThread的子类,所以它的关键方法为doTaskForEveryCompany:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值