在Spring Boot中,@Async注解可以用来创建异步任务。这种方式可以帮助我们在处理一些耗时任务时,避免阻塞主线程,提高系统的处理效率。
解决方案1:
在Spring Boot中,我们可以通过在启动类上添加@EnableAsync注解来启用异步支持。然后在需要异步执行的方法上添加@Async注解。
@SpringBootApplication
@EnableAsync
public class DemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
 
@Service
public class AsyncService {
 
    @Async
    public void asyncMethod() {
        System.out.println("执行异步任务:" + Thread.currentThread().getName());
    }
}
解决方案2:
在@Async注解的方法中,我们可以通过返回Future类型的对象来获取异步执行的结果。
@Service
public class AsyncService {
 
    @Async
    public Future<String> asyncMethod() {
        System.out.println("执行异步任务:" + Thread.currentThread().getName());
        return new AsyncResult<>("异步任务执行完毕");
    }
}
 
@RestController
public class AsyncController {
 
    @Autowired
    private AsyncService asyncService;
 
    @GetMapping("/async")
    public String asyncMethod() throws ExecutionException, InterruptedException {
        Future<String> future = asyncService.asyncMethod();
        return future.get();
    }
}
解决方案3:
在@Async注解的方法中,我们可以通过抛出异常来处理异步执行中可能出现的错误。
@Service
public class AsyncService {
 
    @Async
    public void asyncMethod() {
        System.out.println("执行异步任务:" + Thread.currentThread().getName());
        int i = 10 / 0;
    }
}
 
@Service
public class AsyncService {
 
    @Async
    public void asyncMethod() {
        System.out.println("执行异步任务:" + Thread.currentThread().getName());
        int i = 10 / 0;
    }
 
    @Async
    public void asyncMethodWithException() {
        System.out.println("执行异步任务:" + Thread.currentThread().getName());
        throw new RuntimeException("异步任务执行失败");
    }
}
注意:在使用@Async注解时,如果异步方法中发生了异常,异常并不会被直接抛出到主线程中,因为异步方法返回的是Future类型的对象。我们可以通过Future对象的get方法来获取异常。
解决方案4:
在@Async注解的方法中,我们可以通过自定义线程池来执行异步任务。
@Configuration
public class AsyncConfig implements AsyncConfigurer {
 
    @Override
    @Bean
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setKeepAl