qq_42670060
凌丶志
2021-01-22 09:59

各位大佬springboot 多线程,发现每个子线程运行的时间是递增的,为什么会有这种情况?

  • spring
  • java

      业务逻辑是这样的,要根据不同的时间段,多测向数据查询结果,统一展示到前台,所以我就用了多线程查询。然后就出现了每个子线程运行时间递增的情况,单个子线程的运行时间大概是240毫秒左右,不知道是什么原因导致的。

    //下面是我的代码

@Configuration
@EnableAsync //启用异步
public class AsyncConfiguration implements AsyncConfigurer {

    /**
     * 声明一个线程池
     * @return
     */
    @Bean("taskExecutor")
    public Executor asyncExecutor(){

        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();

        //核心线程数5:线程池创建时候初始化的线程数
        threadPoolTaskExecutor.setCorePoolSize(7);

        //最大线程数5:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        threadPoolTaskExecutor.setMaxPoolSize(10);

        //缓冲队列500:用来缓冲执行任务的队列
        threadPoolTaskExecutor.setQueueCapacity(500);

        //允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
        threadPoolTaskExecutor.setKeepAliveSeconds(60);

        //线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
        threadPoolTaskExecutor.setThreadNamePrefix("DailyAsync-");
    
        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        
        threadPoolTaskExecutor.initialize();

        return threadPoolTaskExecutor;

    }

@Service
@Slf4j
public class SiteClickAsyncService  {

    @Autowired
    private CountPageInfoMapper countPageInfoMapper;
    
    /**
     * 
     * @param startTime
     * @param endTime
     * @param size
     * @return
     */
    @Async("taskExecutor")
    public  CompletableFuture<List<SiteCilckPojo>> getSiteClickTotal(String startTime, String endTime, Integer size){
    
        Instant now = Instant.now();
        log.info("多线程开始,当前线程 -> {},相关参数 -> {} ,  {} , 方法名 -> {}",Thread.currentThread().getName(),startTime,endTime,"getSiteClickTotal");
        List<SiteCilckPojo>  siteClickTotal = countPageInfoMapper.getSiteClickTotal(startTime, endTime, size);
        Instant now1 = Instant.now();
        long between = ChronoUnit.MILLIS.between(now, now1);
        log.warn("当前线程运行时间 -> {}  ,当前线程 -> {},相关参数 -> {} ,  {} , 方法名 -> {}",between,Thread.currentThread().getName(),startTime,endTime,"getSiteClickTotal");
        return CompletableFuture.completedFuture(siteClickTotal);
    
    }
    
    /**
     * 查询 
     * @param startTime
     * @param endTime
     * @return
     */
    @Async("taskExecutor")
    public  CompletableFuture<SiteCilckPojo>  getAllTotal(String startTime, String endTime){
        Instant now = Instant.now();
        log.info("多线程查询的总数开始,当前线程 -> {} ,相关参数 -> {} ,  {} , 方法名 -> {}",Thread.currentThread().getName(),startTime,endTime,"getAllTotal");
        SiteCilckPojo allTotal = countPageInfoMapper.getAllTotal(startTime, endTime);
        Instant now1 = Instant.now();
        long between = ChronoUnit.MILLIS.between(now, now1);
        log.warn("当前线程运行时间 -> {}  ,当前线程 -> {},相关参数 -> {} ,  {} , 方法名 -> {}",between,Thread.currentThread().getName(),startTime,endTime,"getAllTotal");
    
        return CompletableFuture.completedFuture(allTotal);
    }
 @Async("taskExecutor")
    public  CompletableFuture<SiteCilckPojo> getNoTjTotal(String startTime, String endTime){
        Instant now = Instant.now();
        log.info("多线程查询总数开始,当前线程 -> {} ,相关参数 -> {} ,  {} , 方法名 -> {}",Thread.currentThread().getName(),startTime,endTime);
        SiteCilckPojo noTjTotal = countPageInfoMapper.getNoTjTotal(startTime, endTime);
        Instant now1 = Instant.now();
        long between = ChronoUnit.MILLIS.between(now, now1);
        log.warn("当前线程运行时间 -> {}  ,当前线程 -> {},相关参数 -> {} ,  {} , 方法名 -> {}",between,Thread.currentThread().getName(),startTime,endTime,"getNoTjTotal");
    
        return CompletableFuture.completedFuture(noTjTotal);
    }
}

//多线程调用service

 @Override
    public Map<String, Object> getSiteClickOfDept() {
        Map<String, Object> objectObjectHashMap = Maps.newHashMap();
        try {
            Instant now = Instant.now();
            CompletableFuture<List<SiteCilckPojo>> siteClickTotalweek =
                    siteClickAsyncService.getSiteClickTotal(
                            DateUtils.getFirstDayOfWeek(LocalDate.now()), DateUtils.getLastDayOfWeek(LocalDate.now())
                            , 10);
            CompletableFuture<List<SiteCilckPojo>> siteClickTotalmonth =
                    siteClickAsyncService.getSiteClickTotal(
                            DateUtils.getfirstDayOfMonth(LocalDate.now()), DateUtils.getLastDayOfMonth(LocalDate.now())
                            , 10);
            
            CompletableFuture<List<SiteCilckPojo>> siteClickTotal =
                    siteClickAsyncService.getSiteClickTotal(
                            "", ""
                            , 10);
            CompletableFuture<SiteCilckPojo> allTotal = siteClickAsyncService.getAllTotal("", "");
            
            CompletableFuture<SiteCilckPojo> allTotalToday = siteClickAsyncService.getAllTotal(DateUtils.getFirstToday(LocalDate.now()),
                    DateUtils.getLastToday(LocalDate.now()));
            
            CompletableFuture<SiteCilckPojo> allTotalYesterday = siteClickAsyncService.getAllTotal(DateUtils.getFirstYesterday(LocalDate.now()),
                    DateUtils.getLastYesterday(LocalDate.now()));
            
            CompletableFuture<SiteCilckPojo> noTjTotal = siteClickAsyncService.getNoTjTotal("", "");
            
            CompletableFuture<SiteCilckPojo> noTjTotalToday = siteClickAsyncService.getNoTjTotal(DateUtils.getFirstToday(LocalDate.now()),
                    DateUtils.getLastToday(LocalDate.now()));
            
            CompletableFuture<SiteCilckPojo> noTjTotalYesterday = siteClickAsyncService.getNoTjTotal(DateUtils.getFirstYesterday(LocalDate.now()),
                    DateUtils.getLastYesterday(LocalDate.now()));
            
            //join() 的作用:让“主线程”等待“子线程”结束之后才能继续运行
            CompletableFuture.allOf(siteClickTotalweek, siteClickTotalmonth, siteClickTotal).join();
            //周排行
            List<SiteCilckPojo> siteCilckPojos = siteClickTotalweek.get();
            //月排行
            List<SiteCilckPojo> siteCilckPojos1 = siteClickTotalmonth.get();
            //年排行
            List<SiteCilckPojo> siteCilckPojos2 = siteClickTotal.get();
          
            SiteCilckPojo siteCilckPojo = allTotal.get();
         
            SiteCilckPojo siteCilckPojo1 = allTotalToday.get();
         
            SiteCilckPojo siteCilckPojo2 = allTotalYesterday.get();
            
          
            SiteCilckPojo siteCilckPojo3 = noTjTotal.get();
            
           
            SiteCilckPojo siteCilckPojo4 = noTjTotalToday.get();
            
         
            SiteCilckPojo siteCilckPojo5 = noTjTotalYesterday.get();
            CompletableFuture<List<Map<String, Object>>> dataOfDept = siteClickAsyncService.createDataOfDept(siteCilckPojos, siteCilckPojos1, siteCilckPojos2);
            
            CompletableFuture<Map<String, Object>> data = siteClickAsyncService.createData(siteCilckPojo, siteCilckPojo1, siteCilckPojo2, siteCilckPojo3, siteCilckPojo4, siteCilckPojo5);
            //join() 的作用:让“主线程”等待“子线程”结束之后才能继续运行
            CompletableFuture.allOf(dataOfDept, data).join();
            List<Map<String, Object>> maps = dataOfDept.get();
            Map<String, Object> stringObjectMap = data.get();
           
            objectObjectHashMap.put("deptTotal",maps);
            objectObjectHashMap.put("total",stringObjectMap);
            Instant now1 = Instant.now();
            long between = ChronoUnit.MILLIS.between(now, now1);
            System.err.println(Thread.currentThread().getName()+"   运行时间 -》 " + between);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return objectObjectHashMap;
    }

以下是程序运行的日志

  • 点赞
  • 回答
  • 收藏
  • 复制链接分享

1条回答