学习了多线程的理论后,下面我们来看工作中遇到的一个具体实例。
public Integer startAreaIndex(List<Long> activityIds) {
//获取所有常规频道的区块,这里得到的区块为4个,所以最终会启用4个线程
List<Area> areaList = areaServiceStub.queryAreaListByActivityIds(activityIds);
LogTypeEnum.ACTIVITY_SOLR.info("solr开始索引,场频频道活动下的区块list:{}", areaList);
if (CollectionUtils.isEmpty(areaList)) {
return -1;
}
LogTypeEnum.ACTIVITY_SOLR.info("-----------------solr常规频道全量索引开始-----------------");
//一个区块执行一个线程
Iterator<Area> areaIterator = areaList.iterator();
while (areaIterator.hasNext()) {
Area area = areaIterator.next();
AreaApplyTask areaApplyTask = new AreaApplyTask();
areaApplyTask.setArea(area);
areaApplyTask.setSolrWareService(solrWareService); //从这里注入的话,AreaApplyTask 就不用实现Spring的接口了
areaApplyTask.setSolrActivityService(solrActivityService);
areaApplyTask.setSolrPromoService(solrPromoService);
solrIndexTaskExecutor.execute(areaApplyTask);
}
try{
Thread.sleep(1000); //这里先睡眠1秒,防止创建线程的时间长,导致下面第一次取活跃线程数为0,然后就直接break了
}catch (Exception e){
LogTypeEnum.ACTIVITY_SOLR.error("Solr线程索引失败", e);
}
for (; ; ) {
int count = solrIndexTaskExecutor.getActiveCount();
LogTypeEnum.ACTIVITY_SOLR.info("Solr Index Active Threads : " + count);
try {
Thread.sleep(1000); //每隔1秒判断一次活跃线程数
} catch (InterruptedException e) {
LogTypeEnum.ACTIVITY_SOLR.error("Solr线程索引失败", e);
return -1;
}
if (count == 0) {
break;
}
}
return 0;
}
AreaApplyTask类:
public class AreaApplyTask implements Runnable{
private Area area;
private WareService solrWareService;
private PromoService solrPromoService;
private ActivityService solrActivityService;
public void run() {
Area area = getArea();
if(area != null && area.getType() != null){
Integer areaType = area.getType();
if(areaType.equals(AreaType.PROMO.getType())){ //促销区块
//促销
solrPromoService.indexByArea(area);
}else if(areaType.equals(AreaType.WARE.getType())){
//商品
solrWareService.indexByArea(area);
}else if(areaType.equals(AreaType.SHOP.getType())){
//活动
solrActivityService.indexByArea(area);
}else if(AreaType.BRAND.isEqual(areaType)){
//活动
solrActivityService.indexByArea(area);
//促销
solrPromoService.indexByArea(area);
}
}
}
public Area getArea() {
return area;
}
public void setArea(Area area) {
this.area = area;
}
public void setSolrWareService(WareService solrWareService) {
this.solrWareService = solrWareService;
}
public void setSolrPromoService(PromoService solrPromoService) {
this.solrPromoService = solrPromoService;
}
public void setSolrActivityService(ActivityService solrActivityService) {
this.solrActivityService = solrActivityService;
}
}
public long indexByArea(Area area){
/*
这里为了方便多台机器可以同时跑,而且时间可以从页面传过来,采用了redis的方式,这里
key为money,value的值在页面上设的为需要重刷solr的批次日期,例如:2016-12-07 00:00:00|2016-12-08 00:00:00|
这里表示需要重新刷solr的批次日期为12月7日和8日,第一个机器执行后,第二个机器就会跑第二个时间
*/
String key ="money";
String time = activityUtilService.getRedisKeyValue(key);
String beginTime = time.substring(0,time.indexOf("|"));
String nextBeginTime = time.substring(time.indexOf("|")+1);
activityUtilService.setInfoToRedisKey(key,1000*60*60,nextBeginTime);
Batch batch = new Batch();
batch.setActivityId((long)158001);
batch.setBeginTime(DateUtil.createDate(beginTime, "yyyy-MM-dd HH:mm:ss"));
batch.setEndTime(DateUtil.addDay(batch.getBeginTime(),1));
List<Batch> batchList = batchServiceStub.getBatchTimeLineRangeList(batch);
List<Long> batchIdList = new ArrayList<Long>();
for(Batch batch1:batchList){
batchIdList.add(batch1.getId());
}
Long areaId = area.getId();
ApplyWareParam applyWareParam = new ApplyWareParam();
applyWareParam.setBatchIdList(batchIdList);
applyWareParam.setStatus(0);
List<ApplyWare> applyWareList = applyWareServiceStub.getApplyWareListByBatchIds(applyWareParam, 1, 10000);
LogTypeEnum.ACTIVITY_SOLR.warn("applyWareList=="+applyWareList.size()+",areaId="+area.getId());
if(CollectionUtils.isEmpty(applyWareList)){
return -1L;
}
ApplyPromoInfo applyPromoInfoParam = new ApplyPromoInfo();
applyPromoInfoParam.setAreaId(areaId);
//查出该区块下的所有促销提报列表
List<ApplyPromoInfo> applyPromoInfoList = applyPromoInfoDao.queryForList(applyPromoInfoParam,1,Integer.MAX_VALUE);
//把applyPromoInfoList中的促销ID合并到applyWareList中
mergePromoListToWareList(applyWareList,applyPromoInfoList);
return index(applyWareList);
}