@Async
0. 介绍
在Spring 3.x之后,通过内置@Async标明异步方法,可以简化异步开发流程。
@Async既可提供无返回值的调用,也可提供有返回值的调用,下文将分别介绍两种使用方式。
1. 代码Demo
1.1 线程池配置
Spring线程池配置有两种基本配置方式,此处实用其中一种
<task:executor id="myexecutor" pool-size="5" />
<task:annotation-driven executor="myexecutor"/>
1.2 无返回值的调用方式
- 测试类
@Component
public class AsyncTask {
@Async
public void exec() throws Exception{
System.out.println("准备睡觉:" + System.currentTimeMillis());
Thread.sleep(10);
System.out.println("醒了");
}
}
-测试代码
public class AsyncTaskTest extends AbstractTest {
@Autowired
private AsyncTask asyncTask;
@Test
public void testExec() throws Exception {
for (int i= 0; i<5;i++)
asyncTask.exec();
Thread.sleep(1000L);
}
}
- 测试结果
准备睡觉:1511882628039
准备睡觉:1511882628039
准备睡觉:1511882628039
准备睡觉:1511882628039
准备睡觉:1511882628039
醒了
醒了
醒了
醒了
醒了
- 结果分析
从代码输出来看,五个任务在同一时间被执行,说明@Async注解能够达到异步执行方法的目的。
1.3 有返回值的调用
@Async标记的方法,可返回AsyncResult结果,该类为Future子类,因此该类可通过future.get()和future.get(long timeout, TimeUnit unit)拿到返回结果;
- 测试类
@Component
public class AsyncTask {
@Async
public Future<String> exec() throws Exception{
System.out.println("准备睡觉" + System.currentTimeMillis());
Thread.sleep(10);
System.out.println("醒了");
return new AsyncResult<String>("有力气了");
}
}
- 测试代码
public class AsyncTaskTest extends AbstractTest {
@Autowired
private AsyncTask asyncTask;
@Test
public void testExec() throws Exception {
String asyncResult1 = asyncTask.exec().get();
String asyncResult2 = asyncTask.exec().get();
String asyncResult3 = asyncTask.exec().get();
String asyncResult4 = asyncTask.exec().get(50, TimeUnit.MILLISECONDS);
String asyncResult5 = asyncTask.exec().get(50, TimeUnit.MILLISECONDS);
System.out.println("result1:" + asyncResult1);
System.out.println("result2:" + asyncResult2);
System.out.println("result3:" + asyncResult3);
System.out.println("result4:" + asyncResult4);
System.out.println("result5:" + asyncResult5);
}
}
- 测试结果
准备睡觉1511883563474
醒了
准备睡觉1511883563487
醒了
准备睡觉1511883563498
醒了
准备睡觉1511883563510
醒了
准备睡觉1511883563521
醒了
result1:有力气了
result2:有力气了
result3:有力气了
result4:有力气了
result5:有力气了
- 结果分析
通过设置超时时,可在约定时间内获取结果,避免程序hang住,该方法较为实用。