Skip to content

任务执行与调度

约 420 字大约 1 分钟

2025-06-19

JDKExecutors进行了封装抽象,隐藏了环境底层实现

类型

  • 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进行注册