1. 程式人生 > >spring boot非同步(Async)任務排程

spring boot非同步(Async)任務排程

前言

在我前面的部落格中,多處使用了@Async來實現非同步任務排程,具體請參考部落格:

在沒有使用spring boot之前,我們的做法是在配置檔案中定義一個任務池,然後將@Async註解的任務丟到任務池中去執行,那麼在spring boot中,怎麼來實現非同步任務的呼叫了,方法更簡單。

我們還是結合前面

這篇部落格裡面的程式碼來實現。

一、功能說明

消費者在監聽到佇列裡面的訊息時,將接收訊息的任務作為非同步任務處理。

二、程式碼修改

消費者1:

package com.chhliu.springboot.jms;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class Consumer {

	@JmsListener(destination = "mytest.queue")
	@Async //該方法會非同步執行,也就是說主執行緒會直接跳過該方法,而是使用執行緒池中的執行緒來執行該方法
	public void receiveQueue(String text) {
		System.out.println(Thread.currentThread().getName()+":Consumer收到的報文為:"+text);
	}
}
消費者2:
package com.chhliu.springboot.jms;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;

@Component
public class Consumer2 {

	@JmsListener(destination = "mytest.queue")
	@SendTo("out.queue")
	public String receiveQueue(String text) {
		System.out.println(Thread.currentThread().getName()+":Consumer2收到的報文為:"+text);
		return "return message"+text;
	}
}
在測試類上新增如下註解:
package com.chhliu.springboot.jms;

import javax.jms.Destination;

import org.apache.activemq.command.ActiveMQQueue;
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.annotation.EnableAsync;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
@EnableAsync // 開啟非同步任務支援
public class SpringbootJmsApplicationTests {
	
	@Autowired
	private Producer producer;
	
	@Test
	public void contextLoads() throws InterruptedException {
		Destination destination = new ActiveMQQueue("mytest.queue");
		
		for(int i=0; i<100; i++){
			producer.sendMessage(destination, "myname is chhliu!!!");
		}
	}

}
三、測試結果
DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!!
從out.queue佇列收到的回覆報文為:return messagemyname is chhliu!!!
SimpleAsyncTaskExecutor-45:Consumer收到的報文為:myname is chhliu!!!
DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!!
從out.queue佇列收到的回覆報文為:return messagemyname is chhliu!!!
SimpleAsyncTaskExecutor-46:Consumer收到的報文為:myname is chhliu!!!
DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!!
從out.queue佇列收到的回覆報文為:return messagemyname is chhliu!!!
SimpleAsyncTaskExecutor-47:Consumer收到的報文為:myname is chhliu!!!
DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!!
從out.queue佇列收到的回覆報文為:return messagemyname is chhliu!!!
SimpleAsyncTaskExecutor-48:Consumer收到的報文為:myname is chhliu!!!
DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!!
從out.queue佇列收到的回覆報文為:return messagemyname is chhliu!!!
SimpleAsyncTaskExecutor-49:Consumer收到的報文為:myname is chhliu!!!
DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!!
從out.queue佇列收到的回覆報文為:return messagemyname is chhliu!!!
SimpleAsyncTaskExecutor-50:Consumer收到的報文為:myname is chhliu!!!
DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!!
從上面的測試結果可以看出,由於消費者2沒有使用非同步任務方式,所以消費者2消費訊息都是由固定的執行緒DefaultMessageListenerContainer-1這個執行緒來處理的,而消費者1由於使用了非同步任務的方式,每次處理接收到的訊息都是由不同的執行緒來處理的,當接收到訊息時,直接將任務丟到任務池中去處理,而主執行緒則繼續跑,從測試結果中還可以推斷出,spring boot預設使用了newCachedThreadPool執行緒池來實現。

四、非同步任務有返回

在實際的開發中,我們會經常遇到非同步任務有返回的情況,那麼在spring boot中,怎麼來實現了?

下面以非同步發郵件為例,來進行說明,示例程式碼如下:

@Async("taskExecutePool") // 非同步任務會提交到taskExecutePool任務池中執行
	public Future<Response> doSendEmail(MailInfo mailInfo) {// 非同步任務返回,使用Future<Response>來非同步返回
		log.info(Thread.currentThread().getName()+"呼叫了doSendEmail非同步方法!");
		SendMailSession session = null;
		Response res = new Response();
		boolean isOK = sendEmail(mailInfo);// 具體發郵件的方法
    if(isOK){        
        res.setSuccess(true);    
    }else{
        res.setSuccess(false);
    }
 return new AsyncResult<Response>(res);
返回之後怎麼使用?示例程式碼如下:
Future<Response> result = taskJob.doSendEmail(mailInfo);
			res = result.get(6, TimeUnit.SECONDS);
這樣就可以獲取到非同步任務的返回了!

相關推薦

spring boot非同步(Async)任務排程

前言 在我前面的部落格中,多處使用了@Async來實現非同步任務排程,具體請參考部落格: 在沒有使用spring boot之前,我們的做法是在配置檔案中定義一個任務池,然後將@Async註解的任務丟到任務池中去執行,那麼在spring boot中,怎麼來實現非同步任務的

spring boot-執行Async任務時,使用自定義的執行緒池

一、增加配置屬性類 package com.chhliu.springboot.async.configuration; import org.springframework.boot.context.properties.ConfigurationPropertie

Spring之——兩種任務排程Scheduled和Async

轉載請註明出處:http://blog.csdn.net/l1028386804/article/details/72494169 1、Spring排程的兩種方式 Spring提供了兩種後臺任務的方法,分別是:     排

spring boot非同步執行@Async

1.一般非同步執行,使用多執行緒,或者訊息中介軟體完成 2.spring [email protected]可以讓方法非同步執行 package com.example.demo; import org.springframework.scheduling.a

Spring Boot學習(十二)之Spring Boot使用@Async實現非同步呼叫

什麼是“非同步呼叫”?“非同步呼叫”對應的是“同步呼叫”,同步呼叫指程式按照定義順序依次執行,每一行程式都必須等待上一行程式執行完成之後才能執行;非同步呼叫指程式在順序執行時,不等待非同步呼叫的語句返回

Spring Boot使用@Async實現非同步呼叫返回結果:使用Future以及定義超時

關於使用 @Async實現非同步呼叫的內容,也得到不少童鞋的反饋,其中問題比較多的就是關於返回 Future的使用方法以及對非同步執行的超時控制,所以這篇就來一起講講這兩個問題的處理。 如果您對於 @Async註解的使用還不瞭解的話,可以看看之前的文章,具體如下: 定

SpringBoot系列:Spring Boot非同步呼叫@Async

在實際開發中,有時候為了及時處理請求和進行響應,我們可能會多工同時執行,或者先處理主任務,也就是非同步呼叫,非同步呼叫的實現有很多,例如多執行緒、定時任務、訊息佇列等, 這一章節,我們就來講講@Async非同步方法呼叫。 一、@Async使用演示 @Async是Spring內建註解,用來處理非同步任務,在Sp

Spring Boot使用@Async實現異步調用:自定義線程池

tor color HR cal ace 核心 異步 cond cor    前面的章節中,我們介紹了使用@Async註解來實現異步調用,但是,對於這些異步執行的控制是我們保障自身應用健康的基本技能。本文我們就來學習一下,如果通過自定義線程池的方式來控制異步調用的並發。 定

spring boot啟動定時任務

spring logs 例如 info 一次 work frame mage http 1、 定時任務在Spring Boot中的集成 在啟動類中加入開啟定時任務的註解: 在SpringBoot中使用定時任務相當的簡單。首先,我們在啟動類中加入@EnableScheduli

Spring整合quartz定時任務排程的cronExpression配置說明(轉載)

Spring整合quartz定時任務排程 "* * * * * *" 欄位   允許值   允許的特殊字元 秒   

Spring Boot Schedule定時任務要點

 @Scheduled   定時任務可以有很多寫法,我覺得最簡單的就是用註解的方式,如果你的專案用的是spring boot框架,就可以三步完成: 一,新增@EnableScheduling註解到入口類宣告上面 /**  * 啟動  *

spring-boot ---Scheduled 定時任務

package com.shi.snyc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; imp

spring boot 執行緒任務

//任務模組 @Service public class TaskManager extends SimpleEventDispatcher<BaseTask> { private static final Logger log = LoggerFacto

spring boot 執行定時任務

在spring boot專案的啟動類中新增@EnableScheduling註解,表示開啟定時任務,如 @SpringBootApplication @EnableScheduling public

Spring Boot配置定時任務

說明類上帶有@Configuration的類,等同於spring的XML配置檔案,好處是使用Java程式碼可以檢查型別安全。通常還會搭配其他註解來實現不同的需求,如本例中,搭配的@EnableScheduling。在spring-boot中需要在類上新增@EnableScheduling註解來開啟對計劃任務的

spring-boot 分散式定時任務鎖shedlock

先做翻譯: shedlock只做一件事,就是確保計劃任務最多同時執行一次;如果正在一個節點上執行任務,它將獲取一個鎖,以防止從另一個節點(或執行緒)執行相同任務。請注意,過去一個任務已在一個節點上執行,則其他節點上的執行不會等待,只會跳過它;           目前

elastic-job替換掉原來的spring+quartz的定時任務排程

替換的原因: 我想用quartz實現定時任務叢集的時候,遇到過很坑的問題就是所有做叢集的機器都必須保證時間的一致性,要不然有很多機器的專案是起不來的;除此之外,使用quartz很容易造成資料庫死鎖的問題,雖然我已經降低了quartz的資料庫事務級別,但還是有這種情況發生,所

spring boot 整合定時任務quartz配置

<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1

spring boot + quartz定時任務框架入坑指南

quartz Quartz是一個功能豐富的開源作業排程庫,可以整合到幾乎任何Java應用程式中 新增Maven依賴 <!-- druid阿里巴巴資料庫連線池 --> <dependency&

Spring實現後臺的任務排程TimerTask和Quartz

有時候需要啟動一個後臺守護執行緒,做一些別的事情。這時候怎麼獲取spring裡的Service、Dao、Action等物件?(注意自己new一個是不行的,因為脫離了spring的管理,其中IoC資源都沒有被注入)。 一個解決辦法是,重新弄一個Spring:    XmlBeanFactory fa