任务执行与调度
约 420 字大约 1 分钟
2025-06-19
对JDK的Executors进行了封装抽象,隐藏了环境底层实现
类型
- SyncTaskExecutor:运行于调用线程中,不使用异步
- SimpleAsyncTaskExecutor:异步运行,每一个调用都会启动一个新线程(支持使用 JDK21 中的虚拟线程)
- ConcurrentTaskExecutor:对
java.util.concurrent.Executor的适配器,允许实现更灵活的需求 - ThreadPoolTaskExecutor:封装了
java.util.concurrent.ThreadPoolExecutor并支持 Spring 生命周期管理
注解
@Scheduled
添加于一个无返回值且无入参的方法中(顾名思意计划表,无真实调用者,自然不能返回参数与接收参数)
属性
- fixedDelay:周期间隔
- initialDelay:一次性任务,延迟执行
- cron:cron 表达式
@Async
使标记的方法调用异步进行执行,因为有具体的方法调用者,因此@Async能够注释带参数的方法;此外允许使用Future类作为返回类型以查询异步的结果
Future<Integer> future = executor.submit(() -> 1 + 2);
while (!future.isDone()) {
Thread.sleep(100);
}
System.out.println(future.get());使用CompletableFuture实现类能够实现回调异步返回结果
@Test
void asyncTest() throws InterruptedException, ExecutionException {
System.out.println("aaaa");
CompletableFuture<Integer> c = asyncClass.compute(1, 4);
c.thenAccept(System.out::println);
System.out.println("bbbb");
}
@Component
class AsyncClass {
@Async
CompletableFuture<Integer> compute(int a, int b) throws InterruptedException {
Thread.sleep(3000);
return CompletableFuture.completedFuture(a + b);
}
}异常处理
异步进程脱离于主线程,也就意味着其产生的异常无法被主线程所捕获 Spring 提供了AsyncUncaughtExceptionHandler用于处理@Async中未被捕获异常的处理器
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
// handle exception
}
}ex: 抛出的异常method: 发生异常的异步方法params: 方法调用时的参数 需要在AsyncConfigurer进行注册
