2019-05-23 @Async并行

1.常規(guī)代碼順序執(zhí)行

如下定義三個(gè)任務(wù),然后在單元測(cè)試依次調(diào)用三個(gè)任務(wù)原叮,可以看到執(zhí)行結(jié)果是先后執(zhí)行三個(gè)任務(wù)温赔,必須等待前一個(gè)任務(wù)結(jié)束后才能開(kāi)始下一個(gè)任務(wù),總共耗時(shí)6000多毫秒
測(cè)試類

package com.ghw.async;

import javafx.scene.paint.Stop;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.StopWatch;

@RunWith(SpringRunner.class)
@SpringBootTest
public class AsyncApplicationTests {

    @Autowired
    private Task task;

    private static StopWatch stopWatch = new StopWatch();

    @Test
    public void contextLoads() {
    }

    @Test
    public void test() throws Exception {
        task.setStopWatch(stopWatch);
        task.doTaskOne();
        task.doTaskTwo();
        task.doTaskThree();
        System.out.println(stopWatch.prettyPrint());
    }
}

Task類

package com.ghw.async;

import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Component
public class Task {

    private StopWatch stopWatch;

    public void setStopWatch(StopWatch stopWatch) {
        this.stopWatch = stopWatch;
    }

    public void doTaskOne() throws Exception {
        stopWatch.start("task1");
        TimeUnit.SECONDS.sleep(2);
        stopWatch.stop();
    }

    public void doTaskTwo() throws Exception {
        stopWatch.start("task2");
        TimeUnit.SECONDS.sleep(2);
        stopWatch.stop();
    }

    public void doTaskThree() throws Exception {
        stopWatch.start("task3");
        TimeUnit.SECONDS.sleep(2);
        stopWatch.stop();
    }
}

執(zhí)行結(jié)果

StopWatch '': running time (millis) = 6039
-----------------------------------------
ms     %     Task name
-----------------------------------------
02014  033%  task1
02013  033%  task2
02012  033%  task3

2.采用@Async注解異步執(zhí)行

Task類

package com.ghw.async;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Component
public class Task {

    @Async
    public Future<String> doTaskOne() throws Exception {
        StopWatch stopWatch = new StopWatch();
        String task = "task1";
        stopWatch.start(task);
        TimeUnit.SECONDS.sleep(2);
        stopWatch.stop();
        System.out.println(task + " spend time:" + stopWatch.getLastTaskTimeMillis());
        return new AsyncResult<>(task + " is finished");
    }

    @Async
    public Future<String> doTaskTwo() throws Exception {
        StopWatch stopWatch = new StopWatch();
        String task = "task2";
        stopWatch.start(task);
        TimeUnit.SECONDS.sleep(2);
        stopWatch.stop();
        System.out.println(task + " spend time:" + stopWatch.getLastTaskTimeMillis());
        return new AsyncResult<>(task + " is finished");
    }

    @Async
    public Future<String> doTaskThree() throws Exception {
        StopWatch stopWatch = new StopWatch();
        String task = "task3";
        stopWatch.start(task);
        TimeUnit.SECONDS.sleep(2);
        stopWatch.stop();
        System.out.println(task + " spend time:" + stopWatch.getLastTaskTimeMillis());
        return new AsyncResult<>(task + " is finished");
    }
}

測(cè)試類

package com.ghw.async;

import javafx.scene.paint.Stop;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.StopWatch;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@RunWith(SpringRunner.class)
@SpringBootTest
public class AsyncApplicationTests {

    @Autowired
    private Task task;

    private static StopWatch stopWatch = new StopWatch();

    @Test
    public void contextLoads() {
    }

    @Test
    public void test() throws Exception {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("all");
        Future<String> task1 = task.doTaskOne();
        Future<String> task2 = task.doTaskTwo();
        Future<String> task3 = task.doTaskThree();

        while (true) {
            if (task1.isDone() && task2.isDone() && task3.isDone()) {
                // 三個(gè)任務(wù)都調(diào)用完成它褪,退出循環(huán)等待
                break;
            }
        }
        stopWatch.stop();
        System.out.println("all task spend time:" + stopWatch.getLastTaskTimeMillis());
    }
}

執(zhí)行結(jié)果

task3 spend time:2014
task1 spend time:2014
task2 spend time:2014
all task spend time:2060

可以看出只需要2060毫秒饵骨,三個(gè)任務(wù)就全部執(zhí)行完成了,相比第一種方法茫打,能夠提高3倍速度居触。
其中使用Future<T>來(lái)返回異步調(diào)用的結(jié)果。在while循環(huán)中判斷包吝,當(dāng)三個(gè)任務(wù)全部完成的時(shí)候,退出while循環(huán)源葫。

采用自己配置的線程池

package com.ghw.async;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class Task {

    @Async(value = "taskExecutor")
    public void doTaskOne() throws Exception {
        log.info("開(kāi)始做任務(wù)一");
        StopWatch stopWatch = new StopWatch();
        String task = "task1";
        stopWatch.start(task);
        TimeUnit.SECONDS.sleep(2);
        stopWatch.stop();
        log.info("完成任務(wù)一诗越,耗時(shí):" + (stopWatch.getLastTaskTimeMillis()) + "毫秒");
    }

    @Async(value = "taskExecutor")
    public void doTaskTwo() throws Exception {
        log.info("開(kāi)始做任務(wù)二");
        StopWatch stopWatch = new StopWatch();
        String task = "task2";
        stopWatch.start(task);
        TimeUnit.SECONDS.sleep(2);
        stopWatch.stop();
        log.info("完成任務(wù)二,耗時(shí):" + (stopWatch.getLastTaskTimeMillis()) + "毫秒");
    }

    @Async(value = "taskExecutor")
    public void doTaskThree() throws Exception {
        log.info("開(kāi)始做任務(wù)三");
        StopWatch stopWatch = new StopWatch();
        String task = "task3";
        stopWatch.start(task);
        TimeUnit.SECONDS.sleep(2);
        stopWatch.stop();
        log.info("完成任務(wù)三息堂,耗時(shí):" + (stopWatch.getLastTaskTimeMillis()) + "毫秒");
    }
}
package com.ghw.async;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@SpringBootApplication
public class AsyncApplication {

    public static void main(String[] args) {
        SpringApplication.run(AsyncApplication.class, args);
    }

    @EnableAsync
    @Configuration
    class TaskPoolConfig {

        @Bean("taskExecutor")
        public Executor taskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(10);
            executor.setMaxPoolSize(20);
            executor.setQueueCapacity(200);
            executor.setKeepAliveSeconds(60);
            executor.setThreadNamePrefix("taskExecutor-");
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            return executor;
        }
    }
}

單元測(cè)試

package com.ghw.async;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.StopWatch;

@RunWith(SpringRunner.class)
@SpringBootTest
public class AsyncApplicationTests {

    @Autowired
    private Task task;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    private static StopWatch stopWatch = new StopWatch();

    @Test
    public void contextLoads() {
    }

    @Test
    public void test() throws Exception {
        task.doTaskOne();
        task.doTaskTwo();
        task.doTaskThree();
        Thread.currentThread().join();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嚷狞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子荣堰,更是在濱河造成了極大的恐慌床未,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件振坚,死亡現(xiàn)場(chǎng)離奇詭異薇搁,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)渡八,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門啃洋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人屎鳍,你說(shuō)我怎么就攤上這事宏娄。” “怎么了逮壁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵孵坚,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)卖宠,這世上最難降的妖魔是什么巍杈? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮逗堵,結(jié)果婚禮上秉氧,老公的妹妹穿的比我還像新娘。我一直安慰自己蜒秤,他們只是感情好汁咏,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著作媚,像睡著了一般攘滩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纸泡,一...
    開(kāi)封第一講書(shū)人閱讀 49,842評(píng)論 1 290
  • 那天漂问,我揣著相機(jī)與錄音,去河邊找鬼女揭。 笑死蚤假,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吧兔。 我是一名探鬼主播磷仰,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼境蔼!你這毒婦竟也來(lái)了灶平?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤箍土,失蹤者是張志新(化名)和其女友劉穎逢享,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體吴藻,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞒爬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沟堡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疮鲫。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖弦叶,靈堂內(nèi)的尸體忽然破棺而出俊犯,到底是詐尸還是另有隱情,我是刑警寧澤伤哺,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布燕侠,位于F島的核電站者祖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏绢彤。R本人自食惡果不足惜七问,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茫舶。 院中可真熱鬧械巡,春花似錦、人聲如沸饶氏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)疹启。三九已至古程,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間喊崖,已是汗流浹背挣磨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荤懂,地道東北人茁裙。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像节仿,于是被迫代替她去往敵國(guó)和親晤锥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容