每次阅读文章,文章的阅读次数都要+1。
1.为什么要使用线程池来更新阅读次数:
查看文章的时候,我们要将文章的阅读数量+1,这个时候进行了一次更新操作,更新的时候会加写锁,阻塞其他的操作,那么整体查看文章的性能就会比较低,它必须等待新增加观看数量完成后才给前端返回文章详情。
2.解决办法:
利用线程池实现,将更新操作放入到线程池中执行,那么它就和主线程没有关系,也就不会互相影响速度了(这样前端看到的就是更新之前的阅读数量)
3.SpringBoot实现
3.1创建线程池
@Configuration //添加为config
@EnableAsync //开启线程池
public class ThreadPoolConfig {
@Bean("taskExecutor")
public Executor asyncServiceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(5);
// 设置最大线程数
executor.setMaxPoolSize(20);
//配置队列大小
executor.setQueueCapacity(Integer.MAX_VALUE);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(60);
// 设置默认线程名称
executor.setThreadNamePrefix("我的博客项目线程池");
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
//执行初始化
executor.initialize();
return executor;
}
}
3.2新建一个线程Service
@Component
@Slf4j
public class ThreadService {
/**
* 每次阅读文章,文章的阅读数量+1
* 此操作在线程池中执行 不会影响原有的主线程速度
* @param articleMapper
* @param article
*/
@Async("taskExecutor") //利用此注解将当前方法放入到线程池中使用
public void updateArticleViewCount(ArticleMapper articleMapper, Article article) {
//修改文章的阅读数量 数量 +1
Article articleCopy = new Article();
articleCopy.setViewCounts(article.getViewCounts() + 1); //阅读数量+1
QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
//设置修改条件
queryWrapper.eq("id", article.getId());
queryWrapper.eq("view_counts" ,article.getViewCounts() ); // 为了线程安全
//修改
articleMapper.update(articleCopy, queryWrapper);
}
}
3.3利用自动装配新建线程,完成增加阅读量的操作
@Autowired
private ThreadService threadService;
//利用线程池增加文章阅读数量
threadService.updateArticleViewCount(articleMapper,article);
网友评论