@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住,該方法較爲實用。