springboot异步线程(一)
前言
在本篇文章中,我们主要讨论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):
最后
异步线程的一些相关知识知道了。接下来就是怎么去使用了。