@Async 注解的使用

4,193 total views, 3 views today

在 Spring 中,@Async 标注的方法,在执行的时候,是异步运行的,它运行在独立的线程中,程序不会被该方法所阻塞。

使用的时候,需要通过注解@EnableAsync 打开配置,表示可以运行异步的方法。

在异步的方法上面,标注上 @Async 注解即表示该方法是异步运行的。不过需要注意,该方法必须是 public 的,而且,在自身类中,调用异步方法是无效的。

实现异步方法的步骤如下:
第一步,配置文件中,标注可以使用异步@EnableAsync

第二步,实现异步方法,通过@Async 注解。

返回值

实现异步方法有两种类型,一种是无返回值,一种是有返回值。

无返回值的话,和常规写法没什么不同,但是有返回值的话,需要将返回值包在 Future 对象中。Future 对象是专门存放异步响应的一个接口。

演示代码如下:

第三步,调用异步方法。

观察结果:

可以看到,异步方法是立即返回结果值,不会阻塞主线程的。默认的,打开异步开关后,Spring 会使用一个 SimpleAsyncTaskExecutor 作为线程池,该线程默认的并发数是不受限制的。所以每次异步方法来,都会获取一个新线程去运行它。

AsyncConfigurer 接口

Spring 4 中,对异步方法可以做一些配置,将配置类实现 AsyncConfigurer 接口后,可以实现自定义线程池的功能,和统一处理异步方法的异常。

如果不限制并发数,可能会造成系统压力。AsyncConfigurer 接口中的方法 Executor getAsyncExecutor() 实现自定义线程池。控制并发数。

AsyncConfigurer 接口中的方法 public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() 用于处理异步方法的异常。

AsyncUncaughtExceptionHandler 接口,只有一个方法:

void handleUncaughtException(Throwable ex, Method method, Object… params);

因此,AsyncUncaughtExceptionHandler 接口可以认为是一个函数式接口,可以用拉姆达表达式实现该接口。

演示代码如下:

将其中一个异步方法,写一行会产生异常的代码:

如上代码,演示中,将线程池的大小设置成只有 1 个线程,而且其中一个异步方法会有异常。

运行后的结果如下:

可以看到,由于线程池中只有 1 个线程,所以两个异步方法,使用的是同一个线程运行的。异常的处理也由 AsyncUncaughtExceptionHandler 接口处理掉了。

 

原创文章,转载请注明出处!http://www.javathings.top/async注解的使用/

About: wusq


发表评论

电子邮件地址不会被公开。 必填项已用*标注