前言
在本篇文章中,我們主要討論spring異步編程的一些相關知識,不涉及實戰。springboot版本2.2.1
TaskExecutor
spring2.0后提出TaskExecutor
接口,作為任務執行者抽象。TaskExecutor
源碼:
@FunctionalInterface
public interface TaskExecutor extends Executor {
@Override
void execute(Runnable task);
}
spring框架提供了一定的TaskExecutor
實現類,這些實現類可以完成幾乎所有使用場景的覆蓋,所以,大多數情況下,我們沒有必要實現某個TaskExecutor
;
- SyncTaskExecutor
代碼如下:
public class SyncTaskExecutor implements TaskExecutor, Serializable {
@Override
public void execute(Runnable task) {
Assert.notNull(task, "Runnable must not be null");
task.run();
}
}
可以發現,提交給SyncTaskExecutor
的任務都是直接在當前線程中執行
- SimpleAsyncTaskExecutor
@Override
public void execute(Runnable task, long startTimeout) {
Assert.notNull(task, "Runnable must not be null");
Runnable taskToUse = (this.taskDecorator != null ? this.taskDecorator.decorate(task) : task);
if (isThrottleActive() && startTimeout > TIMEOUT_IMMEDIATE) {
this.concurrencyThrottle.beforeAccess();
doExecute(new ConcurrencyThrottlingRunnable(taskToUse));
}
else {
doExecute(taskToUse);
}
}
protected void doExecute(Runnable task) {
Thread thread = (this.threadFactory != null ? this.threadFactory.newThread(task) : createThread(task));
thread.start();
}
提交給SimpleAsyncTaskExecutor
的任務每次都新建一個線程來執行提交的任務。
- ThreadPoolTaskExecutor
如果覺得SimpleAsyncTaskExecutor
每次都需要新建線程不可取,就可以使用這個,ThreadPoolTaskExecutor
改用線程池來管理並重用處理任務異步執行的工作線程。其中,ThreadPoolTaskExecutor
的線程池功能是使用的jdk的ThreadPoolExecutor
來實現的。
@Override
public void execute(Runnable task) {
Executor executor = getThreadPoolExecutor();
try {
executor.execute(task);
}
catch (RejectedExecutionException ex) {
throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex);
}
}
- ConcurrentTaskExecutor
ConcurrentTaskExecutor
為Java5
的Executor
和spring
的TaskExecutor
搭建了一道橋梁使得我們可以將Executor
框架下的某些實現類以TaskExecutor
的形式公開來,如果我們感覺ThreadPoolTaskExecutor
封裝的java.util.concurrent.ThreadPoolExecutor
不足以満足當前場景需要,那么可以構建需要的Executor
實例,比如通過Executors.newXXXThreadPool()
,然后以ConcurrentTaskExecutor
對其進行封裝,封裝后獲得的ConcurrentTaskExecutor
即獲得相應Executor
的能力,但它現在是以TaskExecutor
的樣子示人氣如下所示:
Executor executor =Executors .newScheduledThreadPool (10);
TaskExecutor taskExecutor = new ConcurrentTaskExecutor (executor):
最后
異步線程的一些相關知識知道了。接下來就是怎么去使用了。