Spring多線程
1.概述
Spring通過任務執行器(TaskExecutor)來實現多線程和併發編程。使用ThreadPoolTaskExecutor可實現一個基於線程池的TaskExecutor。而實際開發中任務一般是非阻礙的,即異步的,所以我們要在配置類中通過@EnableAsync開啓對異步任務的支持,並通過在實際執行的Bean的方法中使用@Async註解來聲明其是一個異步任務。
下面通過一個實際的例子來舉例說明。
2.建立包
首先我們在 “src/main/java/com/study/spring/” 下建立一個新的包"ch3.taskexecutor",然後在這個包下再新建3個類,整個項目的結構如下圖所示:
3.定義配置類
配置類TaskExecutorConfig的內容如下:
package com.study.spring.ch3.taskexecutor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@ComponentScan("com.study.spring.ch3.taskexecutor")
@EnableAsync //利用@EnableAsync註解開啓異步任務支持
public class TaskExecutorConfig implements AsyncConfigurer {
public Executor getAsyncExecutor() { //配置類實現AsyncConfigurer接口並重寫getAsyncExecutor方法
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
4.定義任務執行類
任務執行類AsyncTaskService的內容如下:
package com.study.spring.ch3.taskexecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncTaskService {
@Async //通過@Async註解表明該方法是一個異步方法,如果註解在類級別則表示該類的所有方法都是異步方法
public void executeAsyncTask(Integer i){
System.out.println("執行異步任務:"+i);
}
@Async
public void executeAsyncTaskPlus(Integer i){
System.out.println("執行plus異步任務:"+i);
}
}
5.定義測試主類Main
測試主類Main的內容如下:
package com.study.spring.ch3.taskexecutor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class);
for(int i=0;i<10;i++){
asyncTaskService.executeAsyncTask(i);
asyncTaskService.executeAsyncTaskPlus(i+1);
}
context.close();
}
}
6.測試
選擇剛剛建立的測試主類Main文件,右鍵,在彈出的窗體中選擇"Run",效果如下:
從上面的輸出結果可以看出,這是併發執行的,而不是順序執行。