先占个坑,后面补齐
本文主要介绍我们项目在晚上定时执行 job 的时候,由于数据量多,为缩短 job 的执行时间,采用线程池,多线程执行 job 的情况。
先看 job 任务的代码,我只保留了主要的:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* 资产登记表数据同步
*
* @author liusn19096
*/
@Service
public class FsAccountDiagJob {
/**
* 线程数量
*/
private static final int EXENUMS = 20;
/**
* 每次查询的条数
*/
private static final int ROWNUM = 500;
/**
* 线程池.
*/
private ExecutorService exec;
/**
* 定义线程池
*/
public FsAccountDiagJob() {
exec = Executors.newFixedThreadPool(EXENUMS);
}
/**
* job内容
*/
private void doTaskContent(String fund_account, String money_type,
String init_date) {
if (exec == null) {
exec = Executors.newFixedThreadPool(EXENUMS);
}
// 查询条件
Map<String, Object> param = new HashMap<>();
// 一次查询多少条
param.put("rownum", ROWNUM);
// 未处理
param.put("rzdeal_flag", RZDEAL_FLAG);
// 默认计算周期为9
param.put("calculate_cycle", ConstantUtil.DEFAULT_CALCULATE_CYCLE);
// 将参数 资金账户&币种类别 放入查询参数
this.putParamToMap(fund_account, money_type, init_date, param);
// 循环查询
while (true) {
// 查询资产登记表,使用param
List<AssetAndCalculate> list = fsAcctAssetDao
.queryAssetAndCalculate(param);
// 非空
if (!CollectionUtils.isEmpty(list)) {
try {
// 处理数据并更新rzdeal_flag=1
this.dealAssetAndUpdate(list);
} catch (Exception ex) {
LOGGER.error("FsAccountDiagJob.doJob dealAssetAndUpdate",
ex);
}
}
// 最后一次查询或者为空,跳出循环
if (CollectionUtils.isEmpty(list) || list.size() < ROWNUM) {
break;
}
}
LOGGER.info("FsAccountDiagJob end");
}
/**
* 处理数据并更新处理标志
*
* @param list
*/
private void dealAssetAndUpdate(List<AssetAndCalculate> list) {
LOGGER.info("dealAssetAndUpdate START");
List<Future<AccountDiagData>> threadRlt = new ArrayList<>();
List<FsDayRankings> dayRankList = new ArrayList<>();
List<FsStockhold> stockholdList = new ArrayList<>();
List<FsCalculateResult> resultList = new ArrayList<>();
List<FsAcctAsset> assetList = new ArrayList<>();
List<FsCalculateResultDay> resultDayList = new ArrayList<>();
// 循环处理
for (AssetAndCalculate assetAndCalculate : list) {
threadRlt.add(exec.submit(new FsAccountDiagThread(assetAndCalculate,
fsDataStockDao, initasset, fsCsiLogic, fsCalculateResultDao,
fsDeliverDao, fsAcctAssetDao, fsDayRankingsDao)));
}
// 各线程处理结果汇总,保证所有线程执行完之后才能继续下面的代码
for (Future<AccountDiagData> f : threadRlt) {
try {
AccountDiagData data = f.get();
if (data != null) {
if (data.getSuccess()) {
if (data.getAsset() != null) {
assetList.add(data.getAsset());
}
if (data.getDayRank() != null) {
dayRankList.add(data.getDayRank());
}
if (data.getResult() != null) {
resultList.add(data.getResult());
}
if (data.getResultDay() != null) {
resultDayList.add(data.getResultDay());
}
}
}
} catch (Exception e) {
LOGGER.error(e.getLocalizedMessage(), e);
}
}
// 处理成功的数据入库
fsAccountDiagService.saveAccountDiagData(dayRankList, stockholdList,
resultList, assetList, resultDayList);
LOGGER.info("dealAssetAndUpdate END");
}
}
下面看看对应线程 FsAccountDiagThread 类的代码,只保留了主要的:
import java.util.concurrent.Callable;
public class FsAccountDiagThread implements Callable<AccountDiagData> {
/**
* logger.
*/
private static final Logger LOGGER = LoggerFactory
.getLogger(FsAccountDiagThread.class);
private final FsDataStockDao fsDataStockDao;
private final BigDecimal initAsset;
private final IFsCsiLogic fsCsiLogic;
private final FsCalculateResultDao fsCalculateResultDao;
private final FsDeliverDao fsDeliverDao;
private final FsAcctAssetDao fsAcctAssetDao;
private final AssetAndCalculate assetAndCalculate;
private final FsDayRankingsDao fsDayRankingsDao;
@Autowired
public FsAccountDiagThread(AssetAndCalculate assetAndCalculate,
FsDataStockDao fsDataStockDao, BigDecimal initAsset,
IFsCsiLogic fsCsiLogic, FsCalculateResultDao fsCalculateResultDao,
FsDeliverDao fsDeliverDao, FsAcctAssetDao fsAcctAssetDao,
FsDayRankingsDao fsDayRankingsDao) {
// 将dao等service赋值Dao线程
this.assetAndCalculate = assetAndCalculate;
this.fsDataStockDao = fsDataStockDao;
this.initAsset = initAsset;
this.fsCsiLogic = fsCsiLogic;
this.fsCalculateResultDao = fsCalculateResultDao;
this.fsDeliverDao = fsDeliverDao;
this.fsAcctAssetDao = fsAcctAssetDao;
this.fsDayRankingsDao = fsDayRankingsDao;
}
/*
* (non-Javadoc)
*
* @see java.util.concurrent.Callable#call()
*/
@Override
public AccountDiagData call() throws Exception {
AccountDiagData data = new AccountDiagData();
// 进行数据的计算,返回结果data
return data;
}
}
扫描二维码关注公众号,回复:
1900995 查看本文章