jsp做的个人网站,万网域名注册官网电话,semikron,wordpress构建自己的网站shigen坚持更新文章的博客写手#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长#xff0c;分享认知#xff0c;留住感动。 个人IP#xff1a;shigen 在shigen之前的很多文章中#xff0c;提到了线程池#xff1a;
高性能API设计… shigen坚持更新文章的博客写手擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长分享认知留住感动。 个人IPshigen 在shigen之前的很多文章中提到了线程池
高性能API设计一文讲清楚redis的线程池jedis
并配有对应的原理图 在今天重学的时候遇到了这样的问题准备去封装一个线程池的看到了异步线程池的概念。什么异步线程池重新复习了一下。意外收获了一个注解Async。
首先理解一下异步的概念异步是指进程不需要一直等待下去而是继续执行下面的操作不管其他进程的状态。能联系到的最佳的场景是我要下载文件文件要能生成很长的时间不能一直等待对吧。在我的文章《高性能API设计》中就提到了异步思想。 OK那就直接上代码吧。
简单的controller、service GetMapping(value download)public String download() {log.info(开始下载-------);testService.downloadFile();log.info(下载完成-------);return download;}SneakyThrowspublic void downloadFile() {log.info(开始-------);Thread.sleep(10*1000);log.info(结束-------);}相信很多人都是这样写的那再好的服务器找个借口的响应时间都是10s。是的另一端的用户就准备好台词在心里骂设计者100遍了。
一次请求就是一个线程这个线程一直在耗时的文件下载阶段能不阻塞才怪。现在优化点在于实现文件导出的异步。
看代码
定义线程池配置类
写烂了直接复制粘贴。
Configuration
public class AsyncConfig {Bean(asyncExecutor)public Executor asyncExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();// 核心线程数线程池创建时候初始化的线程数executor.setCorePoolSize(10);// 最大线程数线程池最大的线程数只有在缓冲队列满了之后才会申请超过核心线程数的线程executor.setMaxPoolSize(20);// 缓冲队列用来缓冲执行任务的队列executor.setQueueCapacity(500);// 允许线程的空闲时间60秒当超过了核心线程之外的线程在空闲时间到达之后会被销毁executor.setKeepAliveSeconds(60);// 线程池名的前缀设置好了之后可以方便我们定位处理任务所在的线程池executor.setThreadNamePrefix(async-shigen-);// 缓冲队列满了之后的拒绝策略由调用线程处理一般是主线程executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.initialize();return executor;}
}没啥好说的就是线程的名字带了shigen便于区分。
主配置类
加上注解EnableAsync即可。
SpringBootApplication
EnableAsync
MapperScan(basePackages com.shigen.demo.dao)
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}实现类
实现类用的时候就需要线程池了。
Service(testService)
Slf4j
public class TestServiceImpl {/*** 不能和调用方放在同一个类中* a hrefhttps://blog.csdn.net/weixin_45151960/article/details/133988933参考文章/a*/SneakyThrowsAsync(asyncExecutor)public void downloadFile() {log.info(开始-------);Thread.sleep(10*1000);log.info(结束-------);}}代码中已经注明异步方法不能和调用方放在同一个类中。
参考文章 Springboot中开启多线程实现异步非阻塞、异步阻塞、有无返回值的场景 文章代码
测试
本来需要10s的响应时间现在已经是不到1s了。输出的日志如下 表明文件的下载在单独的处理。
最后总结一下参考的博客中的几种场景
场景API异步非阻塞无返回值EnableAsync Async异步非阻塞又返回值场景不存在异步阻塞无返回值CountDownLatch Async异步阻塞又返回值CompletableFuture Async
与shigen一起每天不一样