Spring提供了一個接口
org.springframework.core.task.TaskExecutor
,這個接口實現了java.util.concurrent.Executor
接口,Executor這個接口熟悉多線程的同窗應該都知道,這是java線程池的頂層接口,那也就是說TaskExecutor也是個線程池,經過線程池來執行咱們的異步任務。java
經過xml文件來配置TaskExecutor線程池,具體配置以下。spring
<!-- 代碼中引用便可 @Autowired id:線程池名稱,池中線程的名稱前綴 ThreadPoolTaskExecutor pool-size:單一的值表示核心線程數量,若是是5-25,表示core-max queue-capacity:隊列容量,默認是無界隊列,可能會致使OOM,並且在無界隊列的狀況下,最大線程就無效了,只有固定線程才適合無界隊列 rejection-policy:當都滿了的時候的拒絕策略,AbortPolice,CallerRunsPolicy,DiscardPolicy,DiscardOldestPolicy keep-alive:超過核心線程數量的線程的保活時間,若是設置爲0,表示任務執行完以後當即回收 單位:s -->
<task:executor id="myExecutor" pool-size="5-25" queue-capacity="200" rejection-policy="ABORT" keep-alive="120"/>
複製代碼
從上面的配置咱們能夠看出來,其實就是線程池的經常使用配置。多線程
使用方式:異步
public class MyAsync {
/** * 注入線程池 */
@Autowired
private TaskExecutor taskExecutor;
/** * 無返回值、無參數 */
public void async() {
// taskExecutor.execute(new MyTask());
}
/** * 有參數、無返回值 * * @param param */
public void param(String param) {
// taskExecutor.execute(new MyTask());
}
/** * Future 異步返回 * * @return */
public Future<String> future() {
// taskExecutor.execute(new MyTask());
return new AsyncResult<String>("result");
}
/** * CompletableFuture 異步返回 * * @return */
public CompletableFuture<String> completedFuture() {
// taskExecutor.execute(new MyTask());
return CompletableFuture.completedFuture("result");
}
}
複製代碼
基於xml配置,也能夠配置啓用@Async
註解,具體配置以下:async
<!-- 該標籤是用於開啓註解模式的,識別@Scheduled executor:executor bean name scheduler:scheduler bean name exception-handler:ThreadPoolTaskExecutor exception handler bean name mode:代理方式 1.AspectJ 2.JDK Proxy 默認JDK Proxy proxy-target-class:是否代理目標類 默認false -->
<task:annotation-driven executor="myExecutor"/>
複製代碼
直接使用@Async
註解便可,使用方式以下:ide
public class MyAsync {
/** * 無返回值、無參數 */
@Async
public void async() {
}
/** * 有參數、無返回值 * * @param param */
@Async
public void param(String param) {
}
/** * Future 異步返回 * * @return */
@Async
public Future<String> future() {
return new AsyncResult<String>("result");
}
/** * CompletableFuture 異步返回 * * @return */
@Async
public CompletableFuture<String> completedFuture() {
return CompletableFuture.completedFuture("result");
}
}
複製代碼
基於java config的配置須要實現org.springframework.scheduling.annotation.AsyncConfigurer
接口,具體代碼以下。spa
@Configuration
public class MyAsyncConfigure implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.execute(myTask());
Future<?> future = executor.submit(myTask());
return executor;
}
/** * 異常處理 * * @return */
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
public MyTask myTask() {
return new MyTask();
}
}
複製代碼
基於註解的配置方式是使用@EnableAsync
和@Asyc
兩個註解線程
@Configuration
@EnableAsync //開啓異步,至關於TaskExecutor
public class MyConfiguration {
/** * 配置線程池 * 若是不配置,@EnableAsync默認core-size=1 * * @return */
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor scheduler = new ThreadPoolTaskExecutor();
scheduler.setCorePoolSize(10);
return scheduler;
}
}
複製代碼
使用方式:代理
public class MyAsync {
/** * 無返回值、無參數 */
@Async
public void async() {
}
/** * 有參數、無返回值 * * @param param */
@Async
public void param(String param) {
}
/** * Future 異步返回 * * @return */
@Async
public Future<String> future() {
return new AsyncResult<String>("result");
}
/** * CompletableFuture 異步返回 * * @return */
@Async
public CompletableFuture<String> completedFuture() {
return CompletableFuture.completedFuture("result");
}
}
複製代碼
若是是使用xml配置或註解配置方式,異常處理須要實現org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler
接口,它有一個簡單的實現org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler
,這個實現記錄了異常日誌,咱們也能夠實現這個接口,自定義異常處理。日誌
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
}
}
複製代碼
xml使用:
<!--異常處理-->
<bean id="myAsyncUncaughtExceptionHandler" class="com.ly.task.async.MyAsyncUncaughtExceptionHandler"/>
<task:annotation-driven executor="myExecutor" exception-handler="myAsyncUncaughtExceptionHandler"/>
複製代碼
註解方式只要配置了,發生異常會自動調用。
在上面java config的配置中,咱們實現了org.springframework.scheduling.annotation.AsyncConfigurer
接口來配置,這個接口裏面有一個org.springframework.scheduling.annotation.AsyncConfigurer#getAsyncUncaughtExceptionHandler
方法,直接在這個方法裏進行異常處理便可。