业务场景:
定时任务程序需要分批处理WebService报文数据,每批处理500条数据,循环处理这500条时每一条创建一个线程;
处理完每一批次数据后会更新该批次的状态为已执行状态。
问题:怎样知道这一批次的线程全部执行完成?
使用计数器 CountDownLatch c = new CountDownLatch(resultList.size())
线程每次处理完成后给该计数器减一
最后等计数器的数值为0时,证明该批次全部执行完成,这样就完美解决上边的问题了。。
以下是实际应用代码:
public void executeJob(List<WsExecuteBatch> executeBatchList) {
for (final WsExecuteBatch wsExecuteBatch : executeBatchList) {
final Integer startId = wsExecuteBatch.getStartId();
final Integer endId = wsExecuteBatch.getEndId();
final String orgCode = wsExecuteBatch.getOrgCode();
String sql = "select o from WsRegLog o where o.id>=?1 and o.id<=?2 and o.orgCode=?3";
Query query = medEm.createQuery(sql);
query.setParameter(1, startId);
query.setParameter(2, endId);
query.setParameter(3, orgCode);
List<WsRegLog> resultList = query.getResultList();
final CountDownLatch c = new CountDownLatch(resultList.size());// 线程计数器
for (int i = 0; i < resultList.size(); i++) {
WsRegLog wsRegLog = resultList.get(i);
final Integer logId = wsRegLog.getId();
final String xmlContent = wsRegLog.getContent();
// wsExecuteProcessor.executeTask(orgCode, startId, endId, logId, xmlContent);
es.execute(new Runnable() {// 使用ExecutorService es = Executors.newFixedThreadPool(20);固定长度的线程池,调用线程
@Override
public void run() {
try {
doParseXmlContent(orgCode, startId, endId, logId, xmlContent);
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
} finally {
c.countDown();// 每执行完一个线程,计数器减一
}
}
});
}
try {
c.await();// 阻塞等待,直到CountDownLatch对象的计数值减到0为止
logger.debug("wsExecuteBatch " + startId + " -- " + endId + " execute end !");
// 该批次所有线程都执行完成,更新状态为已执行
// WsExecuteBatch wsExecuteBatch = wsExecuteBatchDao.findByOrgCodeAndStartIdAndEndIdAndStatus(orgCode, startId, endId, 0);
wsExecuteBatch.setStatus(1);
wsExecuteBatchDao.saveAndFlush(wsExecuteBatch);
} catch (InterruptedException e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
}
// try {
// es.shutdown();
// boolean awaitTermination = es.awaitTermination(365, TimeUnit.DAYS);
// while (awaitTermination) {
// // if (es.isTerminated()) {
// Thread.sleep(200);
// logger.debug("wsExecuteBatch " + startId + " -- " + endId + " execute end !");
// // 查到刚刚执行完成的批次,并更新执行状态
// // WsExecuteBatch wsExecuteBatch = wsExecuteBatchDao.findByOrgCodeAndStartIdAndEndIdAndStatus(orgCode, startId, endId, 0);
// wsExecuteBatch.setStatus(1);
// wsExecuteBatchDao.saveAndFlush(wsExecuteBatch);
// break;
// // }
// }
// } catch (InterruptedException e1) {
// e1.printStackTrace();
// }
}
}