/**
* 导入
*
* @return
* @author
*/
@RequestMapping(value = "/sf/import", method = {RequestMethod.POST})
@ResponseBody
@ApiOperation(value = "-导入excel保存", notes = "-导入excel保存", response = String.class)
public BaseResult<Object> sfImportSave(
HttpServletRequest request) throws IOException, InterruptedException {
BaseResult<Object> result = new BaseResult<>();
SysUserRealmDto currentUser = UserUtils.getCurrentUser();
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
List<MultipartFile> fileList = multipartRequest.getFiles("file");
HashMap<String, Long> orgMap = organizationService.findNameId();
if (null != fileList) {
MultipartFile multipartFile = fileList.get(0);
ImporterFactory.Result<SfInformation> list = importerFactory.process(multipartFile.getInputStream(), multipartFile.getOriginalFilename(),
SfInformation.class, SfInformationConfig.class, orgMap);
if (CollectionUtils.isNotEmpty(list.getError())) {
result.setCode(ResultCodeEnum.HTTP_PARAMS_ERROR.getCode());
result.setMsg(list.getErrorByMsg());
return result;
}
SfScheduleDto proc = new SfScheduleDto();
int size = list.getList().size() / 5;//切分粒度,每size条数据,切分一块,交由一条线程处理
int countNum = 0;//当前处理到的位置
List<SfInformation> listRes = list.getList();
int count = listRes.size() / size;//切分块数
int threadNum = 0;//使用线程数
if (count * size != listRes.size()) {
count++;
}
final CountDownLatch countDownLatch = new CountDownLatch(count);
//使用Guava的ListeningExecutorService装饰线程池
ExecutorService executorService = Executors.newFixedThreadPool(count);
List<Future<Map>> futures = new ArrayList<>();
while (countNum < count * size) {
//切割不同的数据块,分段处理
threadNum++;
countNum += size;
MyCallable myCallable = new MyCallable();
myCallable.setOrgId(currentUser.getOrgId());
myCallable.setList(ImmutableList.copyOf(
listRes.subList(countNum - size, listRes.size() > countNum ? countNum : listRes.size())));
myCallable.setCountDownLatch(countDownLatch);
futures.add(executorService.submit(myCallable));
}
/* //回调函数
Futures.addCallback(listenableFuture, new FutureCallback<Map>() {
//任务处理成功时执行
@Override
public void onSuccess(Map map) {
long count1 = countDownLatch.getCount();
System.out.println("第" + count1 + "次处理完成");
countDownLatch.countDown();
countx=countx+ (Integer) map.get("x");
map.get("y");
}
//任务处理失败时执行
@Override
public void onFailure(Throwable throwable) {
countDownLatch.countDown();
System.out.println("处理失败:" + throwable);
}
}, executorService);*/
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
executorService.shutdown();
}
Integer sumx = 0;
Integer sumy = 0;
for (Future<Map> future : futures) {
try {
sumx += (Integer) future.get().get("x");
sumy += (Integer) future.get().get("y");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
proc.setCount(listRes.size());// 总条数
// proc.setProc(sumx + sumy);// 进度 = 导入成功 + 子单号重复
proc.setSuccessCount(sumy);// 导入成功
proc.setDumpCount(sumx);// 子单号重复
// redisTemplate.opsForValue().set(KEY_PREFIX + timestamp, proc, DEFAULT_EXPIRATION_TIMES, TimeUnit.SECONDS);
result.setData(proc);
System.out.println("------------结果处理完毕,返回完毕,使用线程数量:" + threadNum);
result.setMsg(list.getSuccess());
}
}
return result;
}
class MyCallable implements Callable {
private List<SfInformation> list;
private Long orgId;
private CountDownLatch countDownLatch;
@Override
public Object call() throws Exception {
Map map = new HashMap();
int x = 0;
int y = 0;
System.out.println("当前线程名称" + Thread.currentThread());
//模拟对数据处理,然后返回
for (int i = 0; i < list.size(); i++) {
DistributionSet dis = distributionSetService.findCode(list.get(i).getNetCode());
if (dis != null) {
list.get(i).setOrgId(dis.getOrgId());
}
SfInformation sf = sfInformationService.findOrderNo(list.get(i).getOrderNo());
if (sf != null) {
x++;
} else {
list.get(i).setGuideTime(System.currentTimeMillis());
list.get(i).setGuideOrgId(orgId);
sfInformationService.create(list.get(i));
y++;
}
}
countDownLatch.countDown();
map.put("x", x);
map.put("y", y);
return map;
}
public void setList(List<SfInformation> list) {
this.list = list;
}
public void setOrgId(Long orgId) {
this.orgId = orgId;
}
public void setCountDownLatch(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
}
多线程导入execl
最新推荐文章于 2024-03-03 22:50:32 发布