多线程并发执行
package com.qinqiu.job; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSON; import com.qinqiu.api.TraceMainService; import com.qinqiu.api.TraceQueryService; import com.qinqiu.api.TraceSubscribeRecordService; import com.qinqiu.api.TraceSubscribeService; import com.qinqiu.common.enums.BaseScanTypeEnum; import com.qinqiu.common.push.LindormPushDataBaseDO; import com.qinqiu.common.thread.CommonExecutorManager; import com.qinqiu.common.thread.manage.ExecutorConstants; import com.qinqiu.common.util.TraceIdUtil; import com.qinqiu.dto.BaseTraceDTO; import com.qinqiu.dto.BaseWayBillNoDTO; import com.qinqiu.dto.WaybillQueryDTO; import com.qinqiu.entity.TraceSubscribeRecordDO; import com.qinqiu.redis.RedisConstants; import com.qinqiu.redis.RedisManager; import com.qinqiu.redis.lock.DistributedLock; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.time.*; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Stream; /** * 正常对接的快递公司的运单轨迹主动查询完善任务 */ @Component @EnableScheduling @Slf4j(topic = "JOB") public class NormalWaybillTraceJob { /** * 分布式锁 */ @Resource private DistributedLock distributedLock; @Resource private RedisManager redisManager; @Resource private TraceSubscribeRecordService traceSubscribeRecordService; @Resource private TraceMainService traceMainService; @Resource private TraceSubscribeService traceSubscribeService; @Resource private TraceQueryService traceQueryService; private String taskName = "NormalWaybillTraceJob"; private String redisQueryDateKey = "normal_query_trace_jobstate"; private ExecutorService normalWaybillTraceService; @PostConstruct public void init() { CommonExecutorManager.newThreadPool(ExecutorConstants.NORMAL_WAYBILL_TRACE_JOB, 5, 5, 5000); normalWaybillTraceService = CommonExecutorManager.getExecutor(ExecutorConstants.NORMAL_WAYBILL_TRACE_JOB); } /** * 跑的是正常对接的快递公司的任务 * 从某个时间点开始,每隔 */ @Scheduled(cron = "0 0/10 * * * ?") @Async("asyncThread") public void execute() { TraceIdUtil.initTraceId(); LocalDateTime begin = LocalDateTime.now(); log.info("{}启动,{}", taskName, convertTimeToDate(begin)); String lockKey = RedisConstants.REDIS_NORMAL_WAYBILL_TRACE_JOB; boolean tryLock = distributedLock.tryLock(lockKey, 1 * 60 * 60 * 1000, 0); if (!tryLock) { log.info("{}任务尚未完成,redis锁尚未释放:{}", taskName, lockKey); return; } String runKey = tryLock + "/running"; if (!redisManager.hasKey(runKey)) { redisManager.set(runKey, true); } else { log.info("NormalWaybillTraceJob正在执行中..."); return; } // 2021-10-20 00:00:00 Long defaultStartDate = 1634659200000L; // 以此时间点开始 Long redisStartDate = null; AtomicReference<Long> count = new AtomicReference<>(0L); try { if (redisManager.hasKey(redisQueryDateKey)) { redisStartDate = (Long) redisManager.get(redisQueryDateKey); } else { redisStartDate = defaultStartDate; } // 只查询到3天前的未推送签收的数据就终止,下次继续从最开始执行查询 if (redisStartDate > System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 3) { redisManager.set(redisQueryDateKey, defaultStartDate); log.info("未推送签收的数据本轮查询完毕,截至时间点:{}",redisStartDate); return; } List<TraceSubscribeRecordDO> traceSubscribeRecordDOList; do { log.info("{}开始执行:{},count={}", taskName, redisStartDate, count.get()); TraceSubscribeRecordDO traceQueryLogDO = new TraceSubscribeRecordDO(); traceQueryLogDO.setCreateTimeStart(redisStartDate); // 没有完成向商户推送的 traceQueryLogDO.setPushSignStatus(0); // 每次取1万条 traceSubscribeRecordDOList = traceSubscribeRecordService.getNormalSubscribeWaybillTrace(traceQueryLogDO); if (CollectionUtils.isNotEmpty(traceSubscribeRecordDOList)) { Long cycleBegin = redisStartDate; log.info("{}待完善数据:{},traceQueryLogDO:{},start:{},version={}", taskName, traceSubscribeRecordDOList.size(), JSON.toJSONString(traceQueryLogDO), redisStartDate); Stream<TraceSubscribeRecordDO> stream= traceSubscribeRecordDOList.parallelStream(); stream.forEach(m->{ normalWaybillTraceService.submit(() -> { Long start = System.currentTimeMillis(); try { BaseWayBillNoDTO traceData = getTraceInfo(m); if (ObjectUtil.isEmpty(traceData)) { log.info("表和快递公司接口都没有查询到轨迹需要检查是否是正确的单号:{}", JSON.toJSONString(m)); return; } // 将查到的轨迹向订阅的客户推送 traceData.setExpressCompanyCode(m.getExpressCompanyCode()); traceData.setWaybillNo(m.getWaybillNo()); // 需要判断轨迹明细里的快递公司编号是否与订阅表里的快递公司编号一致 traceSubscribeService.sendMerchantsMQ(traceData, false); count.getAndSet(count.get() + 1); } catch (Exception ex) { traceSubscribeRecordService.resetQueryLogisticsNextTime(m); log.error("{}traceQueryLogDO:{},TraceSubscribeRecordDO:{},count={},出现异常:{}", taskName, JSON.toJSONString(traceQueryLogDO), JSON.toJSONString(m), count.get(), ex); } finally { Long end = System.currentTimeMillis(); log.info("本次查询订阅表处理start:{},end:{},cost:{}毫秒", start, end, (end - start)); } }); }); /*new ForkJoinPool(6).submit(() -> stream.parallel().forEach(m -> { Long start = System.currentTimeMillis(); try { BaseWayBillNoDTO traceData = getTraceInfo(m); if (ObjectUtil.isEmpty(traceData)) { log.info("表和快递公司接口都没有查询到轨迹需要检查是否是正确的单号:{}", JSON.toJSONString(m)); return; } // 将查到的轨迹向订阅的客户推送 traceData.setExpressCompanyCode(m.getExpressCompanyCode()); traceData.setWaybillNo(m.getWaybillNo()); // 需要判断轨迹明细里的快递公司编号是否与订阅表里的快递公司编号一致 traceSubscribeService.sendMerchantsMQ(traceData, false); count.getAndSet(count.get() + 1); } catch (Exception ex) { traceSubscribeRecordService.resetQueryLogisticsNextTime(m); log.error("{}traceQueryLogDO:{},TraceSubscribeRecordDO:{},count={},出现异常:{}", taskName, JSON.toJSONString(traceQueryLogDO), JSON.toJSONString(m), count.get(), ex); } finally { Long end = System.currentTimeMillis(); log.info("本次查询订阅表处理start:{},end:{},cost:{}毫秒", start, end, (end - start)); } })).join();*/ /*traceSubscribeRecordDOList.parallelStream().forEach(m -> { Long start = System.currentTimeMillis(); try { BaseWayBillNoDTO traceData = getTraceInfo(m); if (ObjectUtil.isEmpty(traceData)) { log.info("表和快递公司接口都没有查询到轨迹需要检查是否是正确的单号:{}", JSON.toJSONString(m)); return; } // 将查到的轨迹向订阅的客户推送 traceData.setExpressCompanyCode(m.getExpressCompanyCode()); traceData.setWaybillNo(m.getWaybillNo()); // 需要判断轨迹明细里的快递公司编号是否与订阅表里的快递公司编号一致 traceSubscribeService.sendMerchantsMQ(traceData, false); count.getAndSet(count.get() + 1); } catch (Exception ex) { traceSubscribeRecordService.resetQueryLogisticsNextTime(m); log.error("{}traceQueryLogDO:{},TraceSubscribeRecordDO:{},count={},出现异常:{}", taskName, JSON.toJSONString(traceQueryLogDO), JSON.toJSONString(m), count.get(), ex); } finally { Long end = System.currentTimeMillis(); log.info("本次查询订阅表处理start:{},end:{},cost:{}毫秒", start, end, (end - start)); } } );*/ // 设置下一次查询的时间点存储到redis中 比较创建时间 Optional<TraceSubscribeRecordDO> maxData = traceSubscribeRecordDOList.stream().filter(t -> t.getCreateTime() != null) .sorted(Comparator.comparing(TraceSubscribeRecordDO::getCreateTime).reversed()).max((a, b) -> a.getCreateTime().compareTo(b.getCreateTime()) > 0 ? 1 : -1); if (maxData.isPresent()) { TraceSubscribeRecordDO traceSubscribeRecordDOMax = maxData.get(); // 减去1毫秒避免数据遗漏 redisStartDate = traceSubscribeRecordDOMax.getCreateTime() - 1L; redisManager.set(redisQueryDateKey, redisStartDate); log.info("{}设置下次查询时间点:{},本次循环开始时间点:{},count={}", taskName, redisStartDate, cycleBegin, count.get()); } else { log.info("{}有问题设置:{}", taskName, redisStartDate); } } else { log.info("{}数据查询完毕:traceQueryLogDO:{},start:{},count={}", taskName, JSON.toJSONString(traceQueryLogDO), redisStartDate, count.get()); redisManager.set(redisQueryDateKey, defaultStartDate); } } while (CollectionUtils.isNotEmpty(traceSubscribeRecordDOList)); } catch (Exception ex) { log.error("{}任务异常:{}", taskName, ex); } finally { distributedLock.unLock(lockKey); if (redisStartDate != null) { redisManager.set(redisQueryDateKey, redisStartDate); } redisManager.delete(runKey); LocalDateTime end = LocalDateTime.now(); log.info("{}执行完毕,耗时:{}毫秒,共计执行{}条,起始时间:{},结束时间:{},任务结束表的查询时间点:{}", taskName, Duration.between(begin, end).toMillis(), count.get(), convertTimeToDate(begin), convertTimeToDate(end), redisStartDate); } } /** * 直接查轨迹,不考虑轨迹扫描间隔时间,用于按创建时间查询直到最近3天的数据 * * @param m * @return */ private BaseWayBillNoDTO getTraceInfo(TraceSubscribeRecordDO m) { BaseWayBillNoDTO traceData = null; List<BaseTraceDTO> traceDtoList = null; LindormPushDataBaseDO lindormPushData = new LindormPushDataBaseDO(); lindormPushData.setWaybillNo(m.getWaybillNo()); List<LindormPushDataBaseDO> lindormPushDataBaseDOList = traceMainService.queryListSelective(lindormPushData); boolean isQuashou = false; if (CollectionUtils.isNotEmpty(lindormPushDataBaseDOList)) { traceData = traceQueryService.convertBaseWaybillNoDTO(lindormPushDataBaseDOList); traceDtoList = traceData.getWaybillTraces(); isQuashou = traceDtoList.stream().anyMatch(t -> BaseScanTypeEnum.QIAN_SHOU.getDesc().equalsIgnoreCase(t.getOpScanType())); } // 轨迹不是签收状态 请求快递公司接口 if (!isQuashou) { WaybillQueryDTO waybillQueryDTO = new WaybillQueryDTO(); waybillQueryDTO.setWaybillNo(m.getWaybillNo()); waybillQueryDTO.setExpressCompanyCode(m.getExpressCompanyCode()); waybillQueryDTO.setCheckPhoneNo(m.getCheckPhoneNo()); try { List<BaseWayBillNoDTO> waybillDateList = traceQueryService.getExpressNewestData(waybillQueryDTO); if (CollectionUtils.isNotEmpty(waybillDateList)) { traceData = waybillDateList.get(0); traceDtoList = traceData.getWaybillTraces(); if (CollectionUtils.isNotEmpty(traceDtoList)) { // 快递公司接口查到后要入库 traceMainService.batchInsertTraceByBaseWayBill(waybillDateList); } } } catch (Exception ex) { log.error("从快递公司获取轨迹异常getTraceInfo:{}", ex); } } return traceData; } public String convertTimeToDate(LocalDateTime localDateTime) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); return localDateTime.format(formatter); } public static String convertTimeToString(Long time) { Assert.notNull(time, "time is null"); DateTimeFormatter ftf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); return ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault())); } }
package com.qinqiu.job; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSON; import com.qinqiu.api.TraceMainService; import com.qinqiu.api.TraceQueryService; import com.qinqiu.api.TraceSubscribeRecordService; import com.qinqiu.api.TraceSubscribeService; import com.qinqiu.common.enums.BaseScanTypeEnum; import com.qinqiu.common.push.LindormPushDataBaseDO; import com.qinqiu.common.thread.CommonExecutorManager; import com.qinqiu.common.thread.manage.ExecutorConstants; import com.qinqiu.common.util.TraceIdUtil; import com.qinqiu.dto.BaseTraceDTO; import com.qinqiu.dto.BaseWayBillNoDTO; import com.qinqiu.dto.WaybillQueryDTO; import com.qinqiu.entity.TraceSubscribeRecordDO; import com.qinqiu.redis.RedisConstants; import com.qinqiu.redis.RedisManager; import com.qinqiu.redis.lock.DistributedLock; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.time.*; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; /** * 正常对接的快递公司的运单轨迹主动查询完善任务 */ @Component @EnableScheduling @Slf4j(topic = "JOB") public class NormalWaybillTraceJob { /** * 分布式锁 */ @Resource private DistributedLock distributedLock; @Resource private RedisManager redisManager; @Resource private TraceSubscribeRecordService traceSubscribeRecordService; @Resource private TraceMainService traceMainService; @Resource private TraceSubscribeService traceSubscribeService; @Resource private TraceQueryService traceQueryService; private String taskName = "NormalWaybillTraceJob"; private String redisQueryDateKey = "normal_query_trace_jobstate"; private ExecutorService normalWaybillTraceService; @PostConstruct public void init() { CommonExecutorManager.newThreadPool(ExecutorConstants.NORMAL_WAYBILL_TRACE_JOB, 5, 5, 5000); normalWaybillTraceService = CommonExecutorManager.getExecutor(ExecutorConstants.NORMAL_WAYBILL_TRACE_JOB); } /** * 跑的是正常对接的快递公司的任务 * 从某个时间点开始,每隔 */ @Scheduled(cron = "0 0/1 * * * ?") @Async("asyncThread") public void execute() { TraceIdUtil.initTraceId(); LocalDateTime begin = LocalDateTime.now(); log.info("{}启动,{}", taskName, convertTimeToDate(begin)); String lockKey = RedisConstants.REDIS_NORMAL_WAYBILL_TRACE_JOB; boolean tryLock = distributedLock.tryLock(lockKey, 1 * 60 * 60 * 1000, 0); if (!tryLock) { log.info("{}任务尚未完成,redis锁尚未释放:{}", taskName, lockKey); return; } String runKey = tryLock + "/running"; if (!redisManager.hasKey(runKey)) { redisManager.set(runKey, true); } else { log.info("NormalWaybillTraceJob正在执行中..."); return; } // 2021-10-20 00:00:00 Long defaultStartDate = 1634659200000L; // 以此时间点开始 Long redisStartDate = null; AtomicReference<Long> count = new AtomicReference<>(0L); try { if (redisManager.hasKey(redisQueryDateKey)) { redisStartDate = (Long) redisManager.get(redisQueryDateKey); } else { redisStartDate = defaultStartDate; } // 只查询到3天前的未推送签收的数据就终止,下次继续从最开始执行查询 if (redisStartDate > System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 3) { redisManager.set(redisQueryDateKey, defaultStartDate); log.info("未推送签收的数据本轮查询完毕,截至时间点:{}", redisStartDate); return; } List<TraceSubscribeRecordDO> traceSubscribeRecordDOList; do { log.info("{}开始执行:{},count={}", taskName, redisStartDate, count.get()); TraceSubscribeRecordDO traceQueryLogDO = new TraceSubscribeRecordDO(); traceQueryLogDO.setCreateTimeStart(redisStartDate); // 没有完成向商户推送的 traceQueryLogDO.setPushSignStatus(0); // 每次取1万条 traceSubscribeRecordDOList = traceSubscribeRecordService.getNormalSubscribeWaybillTrace(traceQueryLogDO); if (CollectionUtils.isNotEmpty(traceSubscribeRecordDOList)) { Long cycleBegin = redisStartDate; log.info("{}待完善数据:{},traceQueryLogDO:{},start:{},version={}", taskName, traceSubscribeRecordDOList.size(), JSON.toJSONString(traceQueryLogDO), redisStartDate); Stream<TraceSubscribeRecordDO> stream = traceSubscribeRecordDOList.stream(); List<CompletableFuture<String>> futures = stream.map(m -> CompletableFuture.supplyAsync(() -> { // 持续天数的峰值判断的 Long start = System.currentTimeMillis(); try { BaseWayBillNoDTO traceData = getTraceInfo(m); if (ObjectUtil.isEmpty(traceData)) { log.info("表和快递公司接口都没有查询到轨迹需要检查是否是正确的单号:{}", JSON.toJSONString(m)); return "NOTRACE:" + m.getWaybillNo(); } // 将查到的轨迹向订阅的客户推送 到MQ traceData.setExpressCompanyCode(m.getExpressCompanyCode()); traceData.setWaybillNo(m.getWaybillNo()); // 需要判断轨迹明细里的快递公司编号是否与订阅表里的快递公司编号一致 traceSubscribeService.sendMerchantsMQ(traceData, false); count.getAndSet(count.get() + 1); return "OK:" + m.getWaybillNo(); } catch (Exception ex) { traceSubscribeRecordService.resetQueryLogisticsNextTime(m); log.error("{}traceQueryLogDO:{},TraceSubscribeRecordDO:{},count={},出现异常:{}", taskName, JSON.toJSONString(traceQueryLogDO), JSON.toJSONString(m), count.get(), ex); return "ERR:" + m.getWaybillNo(); } finally { Long end = System.currentTimeMillis(); log.info("本次查询订阅表处理start:{},end:{},cost:{}毫秒", start, end, (end - start)); } }, normalWaybillTraceService)).collect(Collectors.toList()); List<String> result = futures.stream() .map(CompletableFuture::join) .collect(Collectors.toList()); // log.info("多线程执行结果:{}", JSON.toJSONString(result)); /*new ForkJoinPool(6).submit(() -> stream.parallel().forEach(m -> { Long start = System.currentTimeMillis(); try { BaseWayBillNoDTO traceData = getTraceInfo(m); if (ObjectUtil.isEmpty(traceData)) { log.info("表和快递公司接口都没有查询到轨迹需要检查是否是正确的单号:{}", JSON.toJSONString(m)); return; } // 将查到的轨迹向订阅的客户推送 traceData.setExpressCompanyCode(m.getExpressCompanyCode()); traceData.setWaybillNo(m.getWaybillNo()); // 需要判断轨迹明细里的快递公司编号是否与订阅表里的快递公司编号一致 traceSubscribeService.sendMerchantsMQ(traceData, false); count.getAndSet(count.get() + 1); } catch (Exception ex) { traceSubscribeRecordService.resetQueryLogisticsNextTime(m); log.error("{}traceQueryLogDO:{},TraceSubscribeRecordDO:{},count={},出现异常:{}", taskName, JSON.toJSONString(traceQueryLogDO), JSON.toJSONString(m), count.get(), ex); } finally { Long end = System.currentTimeMillis(); log.info("本次查询订阅表处理start:{},end:{},cost:{}毫秒", start, end, (end - start)); } })).join();*/ // 设置下一次查询的时间点存储到redis中 比较创建时间 Optional<TraceSubscribeRecordDO> maxData = traceSubscribeRecordDOList.stream().filter(t -> t.getCreateTime() != null) .sorted(Comparator.comparing(TraceSubscribeRecordDO::getCreateTime).reversed()).max((a, b) -> a.getCreateTime().compareTo(b.getCreateTime()) > 0 ? 1 : -1); if (maxData.isPresent()) { TraceSubscribeRecordDO traceSubscribeRecordDOMax = maxData.get(); // 减去1毫秒避免数据遗漏 redisStartDate = traceSubscribeRecordDOMax.getCreateTime(); redisManager.set(redisQueryDateKey, redisStartDate); log.info("{}设置下次查询时间点:{},本次循环开始时间点:{},count={}", taskName, redisStartDate, cycleBegin, count.get()); } else { log.info("{}有问题设置:{}", taskName, redisStartDate); } } else { log.info("{}数据查询完毕:traceQueryLogDO:{},start:{},count={}", taskName, JSON.toJSONString(traceQueryLogDO), redisStartDate, count.get()); redisManager.set(redisQueryDateKey, defaultStartDate); } } while (CollectionUtils.isNotEmpty(traceSubscribeRecordDOList)); } catch (Exception ex) { log.error("{}任务异常:{}", taskName, ex); } finally { distributedLock.unLock(lockKey); if (redisStartDate != null) { redisManager.set(redisQueryDateKey, redisStartDate); } redisManager.delete(runKey); LocalDateTime end = LocalDateTime.now(); log.info("{}执行完毕,耗时:{}毫秒,共计执行{}条,起始时间:{},结束时间:{},任务结束表的查询时间点:{}", taskName, Duration.between(begin, end).toMillis(), count.get(), convertTimeToDate(begin), convertTimeToDate(end), redisStartDate); } } /** * 直接查轨迹,不考虑轨迹扫描间隔时间,用于按创建时间查询直到最近3天的数据 * * @param m * @return */ private BaseWayBillNoDTO getTraceInfo(TraceSubscribeRecordDO m) { BaseWayBillNoDTO traceData = null; List<BaseTraceDTO> traceDtoList = null; LindormPushDataBaseDO lindormPushData = new LindormPushDataBaseDO(); lindormPushData.setWaybillNo(m.getWaybillNo()); List<LindormPushDataBaseDO> lindormPushDataBaseDOList = traceMainService.queryListSelective(lindormPushData); boolean isQuashou = false; if (CollectionUtils.isNotEmpty(lindormPushDataBaseDOList)) { traceData = traceQueryService.convertBaseWaybillNoDTO(lindormPushDataBaseDOList); traceDtoList = traceData.getWaybillTraces(); isQuashou = traceDtoList.stream().anyMatch(t -> BaseScanTypeEnum.QIAN_SHOU.getDesc().equalsIgnoreCase(t.getOpScanType())); } // 轨迹不是签收状态 请求快递公司接口 if (!isQuashou) { WaybillQueryDTO waybillQueryDTO = new WaybillQueryDTO(); waybillQueryDTO.setWaybillNo(m.getWaybillNo()); waybillQueryDTO.setExpressCompanyCode(m.getExpressCompanyCode()); waybillQueryDTO.setCheckPhoneNo(m.getCheckPhoneNo()); try { List<BaseWayBillNoDTO> waybillDateList = traceQueryService.getExpressNewestData(waybillQueryDTO); if (CollectionUtils.isNotEmpty(waybillDateList)) { traceData = waybillDateList.get(0); traceDtoList = traceData.getWaybillTraces(); if (CollectionUtils.isNotEmpty(traceDtoList)) { // 快递公司接口查到后要入库 traceMainService.batchInsertTraceByBaseWayBill(waybillDateList); } } } catch (Exception ex) { log.error("从快递公司获取轨迹异常getTraceInfo:{}", ex); } } return traceData; } public String convertTimeToDate(LocalDateTime localDateTime) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); return localDateTime.format(formatter); } public static String convertTimeToString(Long time) { Assert.notNull(time, "time is null"); DateTimeFormatter ftf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); return ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault())); } }
package com.qinqiu.repository; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; @Slf4j public class Test { public static void main(String [] args){ List<Integer> test = new ArrayList<>(); test.add(1); test.add(2); ExecutorService executor = Executors.newFixedThreadPool(10); List<CompletableFuture<Integer>> futures = test.stream() .map(t -> CompletableFuture.supplyAsync(() -> test(t), executor)) .collect(Collectors.toList()); List<Integer> result = futures.stream() .map(CompletableFuture::join) .collect(Collectors.toList()); log.info("result into:{}", JSON.toJSONString(result)); } private static Integer test(Integer integer){ log.info("test enter into this:{}", integer); return integer; } }