多线程实践(一)

需求背景:

前端发送一个请求,该请求分页查询一份用户列表,然后针对分页中的用户,分别查询每个用户的10个维度的效能指标数据。由于每个维度的数据是在不同的表,并且是对数据进行count(*)操作,因此在这样一个请求过来之后,需要考虑响应性能问题。

一般来说,若只是查询一到两张表,我们会考虑如下的伪代码:

for(user:usserList){
  getUserDate(user);  
}

但在查询数据库时,针对10个维度的查询,为了提高响应的速度,需要考虑将每个用户的数据查询分别起一个线程,然后汇总查询结果。

最终实现代码如下:

public List<JSONObject> getMemberDataByFuture(List<IWantUserDO> pageUser,EfficiencyQueryOption option){
    List<JSONObject> result = new ArrayList<>();
    ExecutorService executor = new ForkJoinPool
        (Runtime.getRuntime().availableProcessors(),
            ForkJoinPool.defaultForkJoinWorkerThreadFactory,
            null, true);

    List<Callable<JSONObject>> callables = pageUser.stream().map(
        userDO -> (Callable<JSONObject>)()->{
            return getEfficiencyVO(userDO,option);
        }
    ).collect(Collectors.toList());

    try{
        result = executor.invokeAll(callables).stream()
            .map(
                future ->{
                    try{
                        return future.get(5,TimeUnit.SECONDS);
                    }catch (Exception e){
                        throw new IllegalStateException(e);
                    }
                }
            ).collect(Collectors.toList());
    }catch (InterruptedException e){

    }
    return result;
}

每个线程查询用户数据的方法如下:

private JSONObject getEfficiencyVO(IWantUserDO userDO,EfficiencyQueryOption queryOption){
    String userNick = userDO.getNickOrName();
    //获取层级
    String jobLevel = userDO.getJobLevel();
    //获取处理的工单数
    int ticketsNum = getUserTicketsNum(userDO,queryOption);
    //获取项目数
    int projectNum = getProjectNum(userDO,queryOption);
    //获取日常项目数
    int dailyProjectNum = getDailyProjectNum(userDO,queryOption);
    //获取需求数
    int reqNum = getRequestsNum(userDO,queryOption);
    //获取bug数
    int bugNum = getBugsNum(userDO,queryOption);
    //获取变更数
    int crNum = getCrNum(userDO,queryOption);
    //获取变更repo数
    int crRepoNum = getCrRepoNum(userDO,queryOption);
    //获取代码行数
    int codeNum = getCodeNum(userDO,queryOption);
    //获取codeReview次数
    int codeReviewNum = getCodeReviewNum(userDO,queryOption);
    JSONObject result = new JSONObject();
    result.put("userNick",userNick);
    result.put("jobLevel",jobLevel);
    result.put("projectNum",projectNum);
    result.put("ticketsNum",ticketsNum);
    result.put("projectNum",projectNum);
    result.put("dailyProjectNum",dailyProjectNum);
    result.put("reqNum",reqNum);
    result.put("bugNum",bugNum);
    result.put("crNum",crNum);
    result.put("crRepoNum",crRepoNum);
    result.put("codeNum",codeNum);
    result.put("codeReviewNum",codeReviewNum);
    return result;
}

 

posted @ 2019-08-30 19:16  sliec  阅读(298)  评论(0编辑  收藏  举报