Springboot執行緒池的使用和擴充套件
我們常用ThreadPoolExecutor提供的執行緒池服務,springboot框架提供了@Async註解,幫助我們更方便的將業務邏輯提交到執行緒池中非同步執行,今天我們就來實戰體驗這個執行緒池服務;
實戰環境
windowns10;
jdk1.8;
springboot 1.5.9.RELEASE;
開發工具:IntelliJ IDEA;
實戰原始碼
本次實戰的原始碼可以在我的GitHub下載,地址:
git@github.com:zq2599/blog_demos.git,
專案主頁:
https://github.com/zq2599/blog_demos
這裡面有多個工程,本次用到的工程為threadpooldemoserver,如下圖紅框所示:
實戰步驟梳理
本次實戰的步驟如下:
建立springboot工程;
建立Service層的介面和實現;
建立controller,開發一個http服務介面,裡面會呼叫service層的服務;
建立執行緒池的配置;
將Service層的服務非同步化,這樣每次呼叫都會都被提交到執行緒池非同步執行;
擴充套件ThreadPoolTaskExecutor,在提交任務到執行緒池的時候可以觀察到當前執行緒池的情況;
建立springboot工程
用IntelliJ IDEA建立一個springboot的web工程threadpooldemoserver,pom.xml內容如下:
xsi:schemaLocation=" ">
4.0.0
com.bolingcavalry
threadpooldemoserver
0.0.1-SNAPSHOT
jar
threadpooldemoserver
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.5.9.RELEASE
<!-- lookup parent from repository -->
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-maven-plugin
建立Service層的介面和實現
建立一個service層的介面AsyncService,如下:
public interface AsyncService {
/**
* 執行非同步任務
*/
void executeAsync();
}
對應的AsyncServiceImpl,實現如下:
@Service
public class AsyncServiceImpl implements AsyncService {
private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);
@Override
public void executeAsync() {
logger.info("start executeAsync");
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
logger.info("end executeAsync");
}
}
這個方法做的事情很簡單:sleep了一秒鐘;
建立controller
建立一個controller為Hello,裡面定義一個http介面,做的事情是呼叫Service層的服務,如下:
@RestController
public class Hello {
private static final Logger logger = LoggerFactory.getLogger(Hello.class);
@Autowired
private AsyncService asyncService;
@RequestMapping("/")
public String submit(){
logger.info("start submit");
//呼叫service層的任務
asyncService.executeAsync();
logger.info("end submit");
return "success";
}
}
至此,我們已經做好了一個http請求的服務,裡面做的事情其實是同步的,接下來我們就開始配置springboot的執行緒池服務,將service層做的事情都提交到執行緒池中去處理;
springboot的執行緒池配置
建立一個配置類ExecutorConfig,用來定義如何建立一個ThreadPoolTaskExecutor,要使用@Configuration和@EnableAsync這兩個註解,表示這是個配置類,並且是執行緒池的配置類,如下所示:
@Configuration
@EnableAsync
public class ExecutorConfig {
private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
@Bean
public Executor asyncServiceExecutor() {
logger.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心執行緒數
executor.setCorePoolSize(5);
//配置最大執行緒數
executor.setMaxPoolSize(5);
//配置佇列大小
executor.setQueueCapacity(99999);
//配置執行緒池中的執行緒的名稱字首
executor.setThreadNamePrefix("async-service-");
// rejection-policy:當pool已經達到max size的時候,如何處理新任務
// CALLER_RUNS:不在新執行緒中執行任務,而是有呼叫者所在的執行緒來執行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//執行初始化
executor.initialize();
return executor;
}
}
注意,上面的方法名稱為asyncServiceExecutor,稍後馬上用到;
將Service層的服務非同步化
開啟AsyncServiceImpl.java,在executeAsync方法上增加註解@Async(“asyncServiceExecutor”),asyncServiceExecutor是前面ExecutorConfig.java中的方法名,表明executeAsync方法進入的執行緒池是asyncServiceExecutor方法建立的,如下:
@Override
@Async("asyncServiceExecutor")
public void executeAsync() {
logger.info("start executeAsync");
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
logger.info("end executeAsync");
}
驗證效果
將這個springboot執行起來(pom.xml所在資料夾下執行mvn spring-boot:run);
在瀏覽器輸入:;
在瀏覽器用F5按鈕快速多重新整理幾次;
在springboot的控制檯看見日誌如下:
2018-01-21 22:43:18.630 INFO 14824 --- [nio-8080-exec-8] c.b.t.controller.Hello : start submit
2018-01-21 22:43:18.630 INFO 14824 --- [nio-8080-exec-8] c.b.t.controller.Hello : end submit
2018-01-21 22:43:18.929 INFO 14824 --- [async-service-1] c.b.t.service.impl.AsyncServiceImpl : end executeAsync
2018-01-21 22:43:18.930 INFO 14824 --- [async-service-1] c.b.t.service.impl.AsyncServiceImpl : start executeAsync
2018-01-21 22:43:19.005 INFO 14824 --- [async-service-2] c.b.t.service.impl.AsyncServiceImpl : end executeAsync
2018-01-21 22:43:19.006 INFO 14824 --- [async-service-2] c.b.t.service.impl.AsyncServiceImpl : start executeAsync
2018-01-21 22:43:19.175 INFO 14824 --- [async-service-3] c.b.t.service.impl.AsyncServiceImpl : end executeAsync
2018-01-21 22:43:19.175 INFO 14824 --- [async-service-3] c.b.t.service.impl.AsyncServiceImpl : start executeAsync
2018-01-21 22:43:19.326 INFO 14824 --- [async-service-4] c.b.t.service.impl.AsyncServiceImpl : end executeAsync
2018-01-21 22:43:19.495 INFO 14824 --- [async-service-5] c.b.t.service.impl.AsyncServiceImpl : end executeAsync
2018-01-21 22:43:19.930 INFO 14824 --- [async-service-1] c.b.t.service.impl.AsyncServiceImpl : end executeAsync
2018-01-21 22:43:20.006 INFO 14824 --- [async-service-2] c.b.t.service.impl.AsyncServiceImpl : end executeAsync
2018-01-21 22:43:20.191 INFO 14824 --- [async-service-3] c.b.t.service.impl.AsyncServiceImpl : end executeAsync
如上日誌所示,我們可以看到controller的執行執行緒是"nio-8080-exec-8",這是tomcat的執行執行緒,而service層的日誌顯示執行緒名為“async-service-1”,顯然已經在我們配置的執行緒池中執行了,並且每次請求中,controller的起始和結束日誌都是連續列印的,表明每次請求都快速響應了,而耗時的操作都留給執行緒池中的執行緒去非同步執行;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3209/viewspace-2807285/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 併發程式設計之執行緒池的使用及擴充套件和優化程式設計執行緒套件優化
- 實戰 | 執行緒池的幾種自定義擴充套件執行緒套件
- SpringBoot執行緒池和Java執行緒池的實現原理Spring Boot執行緒Java
- springboot使用執行緒池(ThreadPoolTaskExecutor)Spring Boot執行緒thread
- springboot中如何使用執行緒池Spring Boot執行緒
- springboot配置執行緒池使用多執行緒插入資料Spring Boot執行緒
- SpringBoot 整合執行緒池Spring Boot執行緒
- Springboot中使用執行緒池的三種方式Spring Boot執行緒
- 執行緒池的建立和使用,執行緒池原始碼初探(篇一)執行緒原始碼
- 執行緒和執行緒池執行緒
- Java執行緒池的使用和原理Java執行緒
- 多執行緒:執行緒池理解和使用總結執行緒
- 執行緒池的使用執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- 【SpringBoot】分析 SpringBoot 中的擴充套件點Spring Boot套件
- 什麼時候執行緒不安全?怎樣做到執行緒安全?怎麼擴充套件執行緒安全的類?執行緒套件
- JAVA執行緒池的使用Java執行緒
- SpringBoot擴充套件點EnvironmentPostProcessorSpring Boot套件
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- 如何優雅的使用和理解執行緒池執行緒
- Python 執行緒池使用Python執行緒
- Springboot非同步任務執行緒池Spring Boot非同步執行緒
- 詳解執行緒池的作用及Java中如何使用執行緒池執行緒Java
- solaris11怎麼擴充套件資源池?solaris11擴充套件資源池的方法套件
- 執行緒池的使用場景執行緒
- 【進階之路】執行緒池擴充與CompletionService操作非同步任務執行緒非同步
- 巧用SpringBoot擴充套件點EnvironmentPostProcessorSpring Boot套件
- SpringBoot-11 擴充套件功能Spring Boot套件
- Java執行緒池二:執行緒池原理Java執行緒
- 使用CreateThreadPool建立執行緒池thread執行緒
- 執行緒池和Executor框架執行緒框架
- Java面試必問之執行緒池的建立使用、執行緒池的核心引數、執行緒池的底層工作原理Java面試執行緒
- 執行緒 執行緒池 Task執行緒
- 多執行緒【執行緒池】執行緒
- 《Java 高階篇》七:執行緒和執行緒池Java執行緒
- JAVA執行緒池的原理及使用Java執行緒
- 如何優雅的使用執行緒池執行緒
- java--執行緒池--建立執行緒池的幾種方式與執行緒池操作詳解Java執行緒