SpringBoot多线程 并行查询接口,并将结果合并返回
多线程并行运行接口并将结果合并返回(调整代码运行速率)
·
1.创建线程池
private static ExecutorService executorService=new ThreadPoolExecutor(10,20,
60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
2.创建接口调用实例(将接口统一放入一个类)
package com.clouderp.order.service.stockimpl;
import com.clouderp.order.dto.GoodsStockDetailDto;
import com.clouderp.order.dto.GoodsStockDto;
import com.clouderp.order.dto.GoodsStockInOutPriceDto;
import com.clouderp.order.mapper.GoodsStockMapper;
import com.clouderp.order.param.GoodsWarehouseParam;
import com.clouderp.order.utils.SpringUtil;
import java.util.*;
import java.util.concurrent.Callable;
/**
* @author Maynard.ran
* @cretetime 2021-09-09 15:21
*/
public class GoodsStockCallableImpl implements Callable<Map<String,Object>> {
/**查询类型**/
private Integer type;
private GoodsWarehouseParam goodsWarehouseParam;
private GoodsStockMapper goodsStockMapper;
public GoodsStockCallableImpl(){}
public GoodsStockCallableImpl(GoodsWarehouseParam param,Integer type){
this.goodsWarehouseParam = param;
this.type = type;
}
@Override
public Map<String, Object> call() throws Exception {
this.goodsStockMapper= SpringUtil.getBean(GoodsStockMapper.class);
Map<String,Object> map = new HashMap<String,Object>();
switch (type){
case 0:
//查询库存中在途数量及在途金额
List<GoodsStockDto> ztStock = goodsStockMapper.findZtStockListBySellerGoodsId(goodsWarehouseParam);
map.put("ztStock",ztStock);
break;
case 1:
List<GoodsStockInOutPriceDto> inNumAndPrice = goodsStockMapper.findInNumAndPrice(goodsWarehouseParam);
map.put("inNumAndPrice",inNumAndPrice);
break;
case 2:
List<GoodsStockInOutPriceDto> inNumAndByPyrkPrice = goodsStockMapper.findInNumAndByPyrkPrice(goodsWarehouseParam);
map.put("inNumAndByPyrkPrice",inNumAndByPyrkPrice);
break;
case 3:
List<GoodsStockInOutPriceDto> outNumBySkuNo = goodsStockMapper.findOutNumBySkuNo(goodsWarehouseParam);
map.put("outNumBySkuNo",outNumBySkuNo);
break;
case 4:
List<GoodsStockInOutPriceDto> outStockPriceBySellerGoodsId = goodsStockMapper.findCgPriceBySellerGoodsId(goodsWarehouseParam);
map.put("outStockPriceBySellerGoodsId",outStockPriceBySellerGoodsId);
break;
case 5:
List<GoodsStockInOutPriceDto> outNumByQcOrPY = goodsStockMapper.findAllOutNumBySkuNo(goodsWarehouseParam);
map.put("outNumByQcOrPY",outNumByQcOrPY);
break;
default:
break;
}
return map;
}
}
3.因为线程问题所以注入mapper文件通过反射方式获取StringUtil.getBean(对应Mapper.class);
package com.clouderp.order.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* 提供手动获取被spring管理的bean对象
*/
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext actx) throws BeansException {
if(this.applicationContext==null){
this.applicationContext=actx;
}
}
/**
* 获取applicationContext
* @return
*/
public static ApplicationContext getApplicationContext(){
return applicationContext;
}
/**
* 通过name获取bean
* @param name
* @return
*/
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
/**
* 通过class获取bean
* @param clazz
* @param <T>
* @return
*/
public static<T>T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及clazz返回的指定的Bean
* @param name
* @param clazz
* @param <T>
* @return
*/
public static<T> T getBean(String name,Class<T>clazz){
return getApplicationContext().getBean(name, clazz);
}
}
4.通过循环调用线程运行不同接口
//存储线程运行完数据
ConcurrentLinkedDeque concurrentLinkedDeque = new ConcurrentLinkedDeque();
//多线程处理获取数据
for (int i = 0; i < 8; i++) {
GoodsWarehouseParam goodsWarehouseParam = new GoodsWarehouseParam();
goodsWarehouseParam.setGoodsData(goodsData);
goodsWarehouseParam.setSkuNoList(skuNoList);
goodsWarehouseParam.setWarehouseId(goodsStockParam.getWarehouseId());
goodsWarehouseParam.setCompanyId(goodsStockParam.getCompanyId());
goodsWarehouseParam.setWarehouseFlag(false);
GoodsStockCallableImpl goodsStockCallable = new GoodsStockCallableImpl(goodsWarehouseParam,i);
Future<Map<String, Object>> submit = executorService.submit(goodsStockCallable);
concurrentLinkedDeque.addFirst(submit);
}
5.循环将数据取出使用 直接Map调用
Map<String,Object> map = new HashMap<String,Object>();
while (concurrentLinkedDeque.size()>0){
Future<Map<String,Object>> first = (Future<Map<String, Object>>) concurrentLinkedDeque.getFirst();
if(first.isDone()){
try {
Map<String, Object> stringObjectMap = first.get();
if(null != stringObjectMap.get("ztStock")){
map.put("ztStock",(List<GoodsStockDto>)stringObjectMap.get("ztStock"));
} else if (null != stringObjectMap.get("inNumAndPrice")) {
map.put("inNumAndPrice",(List<GoodsStockInOutPriceDto>)stringObjectMap.get("inNumAndPrice"));
} else if (null != stringObjectMap.get("inNumAndByPyrkPrice")) {
map.put("inNumAndByPyrkPrice",(List<GoodsStockInOutPriceDto>)stringObjectMap.get("inNumAndByPyrkPrice"));
} else if (null != stringObjectMap.get("outNumBySkuNo")) {
map.put("outNumBySkuNo",(List<GoodsStockInOutPriceDto>)stringObjectMap.get("outNumBySkuNo"));
} else if (null != stringObjectMap.get("outStockPriceBySellerGoodsId")) {
map.put("outStockPriceBySellerGoodsId",(List<GoodsStockInOutPriceDto>)stringObjectMap.get("outStockPriceBySellerGoodsId"));
} else if (null != stringObjectMap.get("outNumByQcOrPY")) {
map.put("outNumByQcOrPY",(List<GoodsStockInOutPriceDto>)stringObjectMap.get("outNumByQcOrPY"));
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
concurrentLinkedDeque.removeFirst();
}
}
return map;
更多推荐
已为社区贡献2条内容
所有评论(0)