目录
1. 原始文章详情页
2. 为什么要使用并发编程升级文章详情页
3. 如何使用并发编程升级文章详情页
3.1 配置线程池
3.2 合并前端请求
3.3 合并后端接口,使用多线程并发执行
4. 项目相关链接
【前端代码】
前端主要做了这四件事:
后端 controller 分别写 4 个接口处理相应的请求即可.
根据前面的前端代码,我们可以看出来,每次访问文章详情页,都会调用 4 个方法,而每一个方法的调用就是一次 HTTP 请求,而 HTTP 请求又是基于 TCP 协议的,所以每一次请求都需要进行 3 次握手,4 次挥手,那么 4 次请求,就需要进行 12 次握手,和 16 次挥手;
这样肯定是不如发送一次 HTTP 请求的性能高的,只不过合并 4 次请求,会使得建立连接和断开连接的时间比原来长那么一点,但是在计算响应的时候,使用了 4 个线程并发执行的,所以整体来说,性能还是可以提升不少的.
@Configuration
public class ThreadPoolConfig {
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5); // 核心线程数
taskExecutor.setMaxPoolSize(10); // 最大线程数
taskExecutor.setQueueCapacity(10000); // 任务队列的大小
taskExecutor.setThreadNamePrefix("my-thread-pool-"); // 前缀名
taskExecutor.initialize();
return taskExecutor;
}
}
/**
* 详情页接口初始化合并方法
* @param aid
* @return
*/
@RequestMapping("/total_init")
public Object totalInit(Integer aid, HttpServletRequest request) throws ExecutionException, InterruptedException {
// 1.非空效验
if(aid == null && aid <= 0) {
return AjaxResult.fail(-1, "非法参数! ");
}
// 2.创建多个任务,放到线程池中进行执行
// 2.1 得到文章详情
FutureTask getArticleInfo = new FutureTask<>(() -> {
// 查询数据库中的文章信息
ArticleInfoVo articleInfoVo = articleService.getDetail(aid);
if(articleInfoVo != null) {
// 组装数据: 查询当前用户发表的文章总数
articleInfoVo.setArtCount(articleService.artCount(articleInfoVo.getUid()));
// 查询图片
UserInfo userInfo = userService.getById(articleInfoVo.getUid());
articleInfoVo.setPhoto(userInfo.getPhoto());
}
return articleInfoVo;
});
// 2.2 得到当前文章的评论列表
FutureTask> getCommentList = new FutureTask<>(() -> {
return commentInfoService.getList(aid);
});
// 2.3 给当前文章的阅读量 + 1
FutureTask updateRCount = new FutureTask<>(() -> {
return articleService.addRCount(aid);
});
// 2.4 当前登录用户的信息返回给前端
FutureTask getSession = new FutureTask<>(() -> {
return SessionUtil.getLoginUser(request);
});
// 将任务放到线程池中并发执行
taskExecutor.submit(getArticleInfo);
taskExecutor.submit(getCommentList);
taskExecutor.submit(updateRCount); // 只操作后端,不需要等待执行完
taskExecutor.submit(getSession);
// 等待任务执行完
ArticleInfoVo articleInfoVo = getArticleInfo.get(); // 阻塞至执行完
List commentList = getCommentList.get();
UserInfo userInfo = getSession.get();
// 3.组装并发执行的结果,返回给前端
HashMap resultMap = new HashMap<>();
resultMap.put("articleinfo",articleInfoVo);
resultMap.put("commentList",commentList);
resultMap.put("userinfo",userInfo);
return AjaxResult.success(resultMap);
}
【注意】后端合并接口后,新的接口需要在拦截器里面设置放行,否则分页列表页查看详情页就会没有权限.
项目仓库:https://gitee.com/xiaobite_hl/JAVA/tree/master/Big-work/mycnblog_ssm_2
项目博客:https://blog.csdn.net/xaiobit_hl/article/details/128727219
项目 web 自动化测试: https://blog.csdn.net/xaiobit_hl/article/details/129903816