Spring異步方法註解 @Async

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章