1. 程式人生 > >SpringBoot實戰(一)——非同步呼叫Async

SpringBoot實戰(一)——非同步呼叫Async

轉自:http://blog.csdn.net/v2sking/article/details/72795742

什麼是非同步呼叫?

非同步呼叫是相對於同步呼叫而言的,同步呼叫是指程式按預定順序一步步執行,每一步必須等到上一步執行完後才能執行,非同步呼叫則無需等待上一步程式執行完即可執行。

如何實現非同步呼叫?

多執行緒,這是很多人第一眼想到的關鍵詞,沒錯,多執行緒就是一種實現非同步呼叫的方式。

在非spring目專案中我們要實現非同步呼叫的就是使用多執行緒方式,可以自己實現Runable介面或者整合Thread類,或者使用jdk1.5以上提供了的Executors執行緒池。

StrngBoot中則提供了很方便的方式執行非同步呼叫。

按照官方示例開擼

程式碼入下

maven依賴:

  1. <parent>  
  2.     <groupId>org.springframework.boot</groupId>  
  3.     <artifactId>spring-boot-starter-parent</artifactId>  
  4.     <version>1.5.3.RELEASE</version>  
  5. </parent>  
  6. <dependencies>  
  7.     <dependency>  
  8.         <groupId>org.springframework.boot</groupId>  
  9.         <artifactId>spring-boot-starter-web</artifactId>  
  10.     </dependency>  
  11. </dependencies>  
啟動類:新增@EnableAsync註解
  1. @SpringBootApplication
  2. @EnableAsync
  3. publicclass Application{  
  4.     publicstaticvoid main(String[] args) {  
  5.         SpringApplication.run(Application.class, args);  
  6.     }  
  7. }  


Controller 

只需在需要非同步執行方法上新增@Async註解

  1. @RestController
  2. @RequestMapping("")  
  3. publicclass AsyncTaskController {  
  4.     @RequestMapping("")  
  5.     public String doTask() throws InterruptedException{  
  6.         long currentTimeMillis = System.currentTimeMillis();  
  7.         this.task1();  
  8.         this.task2();  
  9.         this.task3();  
  10.         long currentTimeMillis1 = System.currentTimeMillis();  
  11.         return"task任務總耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms";  
  12.     }  
  13.     @Async
  14.     publicvoid task1() throws InterruptedException{  
  15.         long currentTimeMillis = System.currentTimeMillis();  
  16.         Thread.sleep(1000);  
  17.         long currentTimeMillis1 = System.currentTimeMillis();  
  18.         System.out.println("task1任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");  
  19.     }  
  20.     @Async
  21.     publicvoid task2() throws InterruptedException{  
  22.         long currentTimeMillis = System.currentTimeMillis();  
  23.         Thread.sleep(2000);  
  24.         long currentTimeMillis1 = System.currentTimeMillis();  
  25.         System.out.println("task2任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");  
  26.     }  
  27.     @Async
  28.     publicvoid task3() throws InterruptedException{  
  29.         long currentTimeMillis = System.currentTimeMillis();  
  30.         Thread.sleep(3000);  
  31.         long currentTimeMillis1 = System.currentTimeMillis();  
  32.         System.out.println("task3任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");  
  33.     }  
  34. }  
main函式執行spirngboot專案,啟動完成後瀏覽器訪問:

http://localhost:8080/

控制檯:

  1. task1任務耗時:1012ms  
  2. task2任務耗時:2009ms  
  3. task3任務耗時:3004ms  

等了一段瀏覽器時候輸出入下:

  1. task任務總耗時:6002ms   


非同步並沒有執行!

難道是程式碼寫錯了?反覆檢查了好幾遍,並沒有發現什麼明顯錯誤,想起spring對@Transactional註解時也有類似問題,spring掃描時具有@Transactional註解方法的類時,是生成一個代理類,由代理類去開啟關閉事務,而在同一個類中方法呼叫是在類體內執行的,spring無法截獲這個方法呼叫。

豁然開朗,將非同步任務單獨放到一個類中,調整程式碼入下:

Controller

  1. @RequestMapping("")  
  2. @RestController
  3. publicclass AsyncTaskController {  
  4.     @Autowired
  5.     private AsyncTask asyncTask;  
  6.     @RequestMapping("")  
  7.     public String doTask() throws InterruptedException{  
  8.         long currentTimeMillis = System.currentTimeMillis();  
  9.         asyncTask.task1();  
  10.         asyncTask.task2();  
  11.         asyncTask.task3();  
  12.         long currentTimeMillis1 = System.currentTimeMillis();  
  13.         return"task任務總耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms";  
  14.     }  
  15. }  
非同步任務類
  1. @Component
  2. publicclass AsyncTask {  
  3.     @Async
  4.     publicvoid task1() throws InterruptedException{  
  5.         long currentTimeMillis = System.currentTimeMillis();  
  6.         Thread.sleep(1000);  
  7.         long currentTimeMillis1 = System.currentTimeMillis();  
  8.         System.out.println("task1任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");  
  9.     }  
  10.     @Async
  11.     publicvoid task2() throws InterruptedException{  
  12.         long currentTimeMillis = System.currentTimeMillis();  
  13.         Thread.sleep(2000);  
  14.         long currentTimeMillis1 = System.currentTimeMillis();  
  15.         System.out.println("task2任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");  
  16.     }  
  17.     @Async
  18.     publicvoid task3() throws InterruptedException{  
  19.         long currentTimeMillis = System.currentTimeMillis();  
  20.         Thread.sleep(3000);  
  21.         long currentTimeMillis1 = System.currentTimeMillis();  
  22.         System.out.println("task3任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");  
  23.     }  
  24. }  

控制檯:

  1. task1任務耗時:1012ms  
  2. task2任務耗時:2009ms  
  3. task3任務耗時:3004ms  

訪問瀏覽器結果入下:
  1. task任務總耗時:19ms  

非同步呼叫成功!

如何知道三個非同步任務什麼時候執行完,執行的結果怎樣呢?可以採用新增Fature回撥方式判斷

程式碼入下:

非同步任務類

  1. @Component
  2. publicclass AsyncTask {  
  3.     @Async
  4.     public Future<String> task1() throws InterruptedException{  
  5.         long currentTimeMillis = System.currentTimeMillis();  
  6.         Thread.sleep(1000);  
  7.         long currentTimeMillis1 = System.currentTimeMillis();  
  8.         System.out.println("task1任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");  
  9.         returnnew AsyncResult<String>("task1執行完畢");  
  10.     }  
  11.     @Async
  12.     public Future<String> task2() throws InterruptedException{  
  13.         long currentTimeMillis = System.currentTimeMillis();  
  14.         Thread.sleep(2000);  
  15.         long currentTimeMillis1 = System.currentTimeMillis();  
  16.         System.out.println("task2任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");  
  17.         returnnew AsyncResult<String>("task2執行完畢");  
  18.     }  
  19.     @Async
  20.     public Future<String> task3() throws InterruptedException{  
  21.         

    相關推薦

    SpringBoot實戰——非同步呼叫Async

    轉自:http://blog.csdn.net/v2sking/article/details/72795742什麼是非同步呼叫?非同步呼叫是相對於同步呼叫而言的,同步呼叫是指程式按預定順序一步步執行,每一步必須等到上一步執行完後才能執行,非同步呼叫則無需等待上一步程式執行完

    SpringBoot整合篇 非同步呼叫Async

    什麼是非同步呼叫? 非同步呼叫是相對於同步呼叫而言的,同步呼叫是指程式按預定順序一步步執行,每一步必須等到上一步執行完後才能執行,非同步呼叫則無需等待上一步程式執行完即可執行。 如何實現非同步呼叫? 多執行緒,這是很多人第一眼想到的關鍵詞,沒錯,多執行緒就是一種實現非同步

    Springboot214非同步呼叫Async

    原始碼地址 非同步呼叫相對於同步呼叫而言,通常的方法都是程式按照順序來執行的,程式的每一步都需要等到上一步執行完成之後才能繼續往下執行;而非同步呼叫則無需等待,它可以在不阻塞主執行緒的情況下執行高耗時方法 文章目錄

    多執行緒實戰——多執行緒輪流呼叫

    師傅留了一個作業讓我們來熟悉多執行緒問題,原本對多執行緒一直處於理論階段,大二學作業系統的時候寫的也是一知半解,今天拿到這道題又好好的做了一遍。 題目:稽核系統有一批工單需要處理,現在啟動三個執行緒進行處理,要求執行緒1處理工單id mod 3 = 1的工單,執行緒2處理工

    Spring 事務配置實戰:過濾無需事務處理的查詢之類操作

    log pla ssi pan spl tail gif aop img <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes

    RabbitMq 實戰

    rabbitmq spring boot (消費者處理消息)RabbitMq消息消費者服務 開發工具Idea和Spring boot來開發的。消息消費目前只是一個簡單的Demo,後續會處理成更智能一些。首先配置文件類,RabbitMqConfig,裏面配置一些用戶名和密碼嗨喲隊列信息。package com.

    Wicket實戰概述

    rac span 下載 本質 jsf xtend 公式 href tar 今天給大家介紹一個很好的東西。一個被稱作Java平臺上的ASP.NET——Wicket。 什麽是Wicket 什麽是Wicket,假設你用谷歌或其它

    Linux系統集群架構線上項目配置實戰

    linux 項目 實戰 Linux系統集群架構線上項目配置實戰(一)本文出自 “民工哥博客” 博客,請務必保留此出處http://mingongge.blog.51cto.com/2429897/1971210Linux系統集群架構線上項目配置實戰(一)

    機器學習實戰—— 用線性回歸預測波士頓房價

    -1 png 機器學習 mage 回歸 線性回歸 blog 分享 機器 機器學習實戰(一)—— 用線性回歸預測波士頓房價

    全棧性能測試修煉寶典--Jmeter實戰

    div 測試用例 ceo 上下文切換 知識 能力 熱點 mongo rac 性能測試方向職業發展 1、軟件測試發展路線   我們可以暫且把軟件測試職業路線分為3個方向,分別是業務路線、技術路線、管理路線;4個象限,分別為執行層、中層、中高層過渡、高層。   (1)業務路線

    mmall 項目實戰項目初始化

    ant log 初始 post gpo using base inno ole 1.創建 數據庫 及 表 數據腳本: /* Navicat Premium Data Transfer Source Server : 182.92.82.1

    Docker從入門到實戰

    roc serve net lin 軟件 系統調用 生命 etc before 一步一步走,寫小白都能看懂的文章,將持續更新中,敬請期待! Docker從入門到實戰(一) 一:容器技術與Docker概念 1 什麽是容器 容器技術並不是一個全新的概念,它又稱為容器虛擬化。虛擬

    MySQL數據庫從入門到實戰

    DBA體系 mysql 非關系型數據庫 SQL優化 第一部分:了解DBA體系一、初級DBA應該掌握哪些技能?(運維人員必會知識)1.MySQL安裝部署2.基本參數配置3.備份策略設計與實現 二、中級DBA應該掌握哪些技能?1.故障處理能力(備份或者其他手段)2.MySQL監控能力3.基本優化能

    自動化運維工具Ansible實戰簡介和部署

    Ansible 自動化運維 一、Ansible的介紹 Ansible是新出現的自動化運維工具,基於Python開發,集合了眾多運維工具(puppet、cfengine、chef、func、fabric)的優點。實現了批量系統配置、批量程序部署、批量運行命令等功能。Ansible是基於模塊工作的,本身沒

    Android項目實戰: SpannableString與SpannableStringBuilder

    append() 同時 uil 註意 1.5 查看 strong 尊重 bject 原文:Android項目實戰(一): SpannableString與SpannableStringBuilder前言: 曾經在一些APP中的一些類似“幫助”&ld

    Laravel 完整實戰 —— 搭建及配置

    laravel composer 實戰 環境: nginx + php + mysql laravel : 5.5開發環境的搭建略過 安裝 laravel composer create-project laravel/laravel [project-name] --prefer-dist

    Spark實戰SparkStreaming集成Kafka

    round 形式 寫入 some base cal 接下來 會話 支持 Spark Streaming + Kafka集成指南 Kafka項目在版本0.8和0.10之間引入了一個新的消費者API,因此有兩個獨立的相應Spark Streaming包可用。請選擇正確的包,

    SpringBoot學習——Spring的發展

    spa java類 配置文件 實踐 項目 ice bsp 配置 學習 一、Spring1.x時代   在Spring1.x時代,都是通過xml文件配置bean,隨著項目的不斷擴大,需要將xml配置分放到不同的配置文件中,需要頻繁的在Java類和xml配置文件中切換。 二

    Docker基礎入門實戰

    art The 開機自啟動 inf 應用程序 51cto 管理 x86 正在 Docker基礎入門實戰第1章 docker簡介1.1 what is DockerDocker是一個開源的應用容器引擎,基於Go語言並遵從Apache2.0協議開源,源代碼部

    SpringBoot入門——開箱即用

    工程 新建 入門 專註 原則 無需 編寫 部署 sel 本文來自網易雲社區 Spring Boot是什麽 從根本上來講Spring Boot就是一些庫的集合,是一個基於“約定優於配置”的原則,快速搭建應用的框架。本質上依然Spring,在這之上幫我們省去了很多樣板化的配