真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Springboot中怎么利用WebAsyncTask實(shí)現(xiàn)異步任務(wù)編程

今天就跟大家聊聊有關(guān)Spring boot中怎么利用WebAsyncTask實(shí)現(xiàn)異步任務(wù)編程,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿(mǎn)足客戶(hù)于互聯(lián)網(wǎng)時(shí)代的方山網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

1、處理線程

處理線程屬于web服務(wù)器,負(fù)責(zé)處理用戶(hù)請(qǐng)求,采用線程池管理

2、異步線程

異步線程屬于用戶(hù)自定義的線程,可采用線程池管理

spring中提供了對(duì)異步任務(wù)的支持,采用 WebAsyncTask 類(lèi)即可實(shí)現(xiàn)異步任務(wù),同時(shí)我們也可以對(duì)異步任務(wù)設(shè)置相應(yīng)的回調(diào)處理,如當(dāng)任務(wù)超時(shí)、拋出異常怎么處理等。異步任務(wù)通常非常實(shí)用,比如我們想讓一個(gè)可能會(huì)處理很長(zhǎng)時(shí)間的操作交給異步線程去處理,又或者當(dāng)一筆訂單支付完成之后,開(kāi)啟異步任務(wù)查詢(xún)訂單的支付結(jié)果。

一、正常異步任務(wù)

為了演示方便,異步任務(wù)的執(zhí)行采用 Thread.sleep(long) 模擬,現(xiàn)在假設(shè)用戶(hù)請(qǐng)求以下接口 :

http://localhost:7000/demo/getUserWithNoThing.json

異步任務(wù)接口定義如下:

/**
 * 測(cè)試沒(méi)有發(fā)生任何異常的異步任務(wù)
 */
@RequestMapping(value = "getUserWithNoThing.json", method = RequestMethod.GET)
public WebAsyncTask getUserWithNoThing() {
 // 打印處理線程名
 System.err.println("The main Thread name is " + Thread.currentThread().getName());
 
 // 此處模擬開(kāi)啟一個(gè)異步任務(wù),超時(shí)時(shí)間為10s
 WebAsyncTask task1 = new WebAsyncTask(10 * 1000L, () -> {
 	System.err.println("The first Thread name is " + Thread.currentThread().getName());
 	// 任務(wù)處理時(shí)間5s,不超時(shí)
 	Thread.sleep(5 * 1000L);
 	return "任務(wù)1順利執(zhí)行成功!任何異常都沒(méi)有拋出!";
 });
 
 // 任務(wù)執(zhí)行完成時(shí)調(diào)用該方法
 task1.onCompletion(() -> {
 	System.err.println("任務(wù)1執(zhí)行完成啦!");
 });
 
 System.err.println("task1繼續(xù)處理其他事情!");
 return task1;
}

控制臺(tái)打印如下:

The main Thread name is http-nio-7000-exec-1
task1繼續(xù)處理其他事情!
The first Thread name is MvcAsync1
任務(wù)1執(zhí)行完成啦!

瀏覽器結(jié)果如下:

Spring boot中怎么利用WebAsyncTask實(shí)現(xiàn)異步任務(wù)編程 

二、拋異常異步任務(wù)

接口調(diào)用 : http://localhost:7000/demo/getUserWithError.json

/**
 * 測(cè)試發(fā)生error的異步任務(wù)
 * @return
 */
@RequestMapping(value = "getUserWithError.json", method = RequestMethod.GET)
public WebAsyncTask getUserWithError() {
	System.err.println("The main Thread name is " + Thread.currentThread().getName());

	// 此處模擬開(kāi)啟一個(gè)異步任務(wù)
	WebAsyncTask task3 = new WebAsyncTask(10 * 1000L, () -> {
		System.err.println("The second Thread name is " + Thread.currentThread().getName());
		// 此處拋出異常
		int num = 9 / 0;
		System.err.println(num);
		return "";
	});

	// 發(fā)生異常時(shí)調(diào)用該方法
	task3.onError(() -> {
		System.err.println("====================================" + Thread.currentThread().getName()
				+ "==============================");
		System.err.println("任務(wù)3發(fā)生error啦!");
		return "";
	});
	// 任務(wù)執(zhí)行完成時(shí)調(diào)用該方法
	task3.onCompletion(() -> {
		System.err.println("任務(wù)3執(zhí)行完成啦!");
	});

	System.err.println("task3繼續(xù)處理其他事情!");
	return task3;
}

控制臺(tái)輸出如下:

The main Thread name is http-nio-7000-exec-1
task3繼續(xù)處理其他事情!
The second Thread name is MvcAsync1
2018-06-15 09:40:13.538 ERROR 9168 --- [nio-7000-exec-2] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] threw exception

java.lang.ArithmeticException: / by zero
at com.example.demo.controller.GetUserInfoController.lambda$5(GetUserInfoController.java:93) ~[classes/:na]
at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:317) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_161]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_161]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_161]

2018-06-15 09:40:13.539 ERROR 9168 --- [nio-7000-exec-2] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [/demo] threw exception [Request processing failed; nested exception is java.lang.ArithmeticException: / by zero] with root cause

java.lang.ArithmeticException: / by zero
at com.example.demo.controller.GetUserInfoController.lambda$5(GetUserInfoController.java:93) ~[classes/:na]
at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:317) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_161]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_161]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_161]

====================================http-nio-7000-exec-2==============================
任務(wù)3發(fā)生error啦!
任務(wù)3執(zhí)行完成啦!

當(dāng)然你也可以對(duì)上面做一些異常處理,不至于在用戶(hù)看來(lái)顯得不友好,關(guān)于異常處理,可以查看我的另一篇文章 Spring boot/Spring 統(tǒng)一錯(cuò)誤處理方案的使用

瀏覽器輸出結(jié)果:

Spring boot中怎么利用WebAsyncTask實(shí)現(xiàn)異步任務(wù)編程 

三、超時(shí)異步任務(wù)

接口調(diào)用 : http://localhost:7000/demo/getUserWithTimeOut.json

/**
 * 測(cè)試發(fā)生任務(wù)超時(shí)的異步任務(wù)
 * @return
 */
@RequestMapping(value = "getUserWithTimeOut.json", method = RequestMethod.GET)
public WebAsyncTask getUserWithTimeOut() {
 System.err.println("The main Thread name is " + Thread.currentThread().getName());
 
 // 此處模擬開(kāi)啟一個(gè)異步任務(wù),超時(shí)10s
 WebAsyncTask task2 = new WebAsyncTask(10 * 1000L, () -> {
 	System.err.println("The second Thread name is " + Thread.currentThread().getName());
 	Thread.sleep(20 * 1000L);
 	return "任務(wù)2執(zhí)行超時(shí)!";
 });
 
 // 任務(wù)超時(shí)調(diào)用該方法
 task2.onTimeout(() -> {
 	System.err.println("====================================" + Thread.currentThread().getName()
 			+ "==============================");
 	return "任務(wù)2發(fā)生超時(shí)啦!";
 });
 
 // 任務(wù)執(zhí)行完成時(shí)調(diào)用該方法
 task2.onCompletion(() -> {
 	System.err.println("任務(wù)2執(zhí)行完成啦!");
 });
 
 System.err.println("task2繼續(xù)處理其他事情!");
 return task2;
}

控制臺(tái)執(zhí)行結(jié)果:

The main Thread name is http-nio-7000-exec-4
task2繼續(xù)處理其他事情!
The second Thread name is MvcAsync2
====================================http-nio-7000-exec-5==============================
任務(wù)2執(zhí)行完成啦!

瀏覽器執(zhí)行結(jié)果:

Spring boot中怎么利用WebAsyncTask實(shí)現(xiàn)異步任務(wù)編程 

四、線程池異步任務(wù)

上面的三種情況中的異步任務(wù)默認(rèn)不是采用線程池機(jī)制進(jìn)行管理的,也就是說(shuō),一個(gè)請(qǐng)求進(jìn)來(lái),雖然釋放了處理線程,但是系統(tǒng)依舊會(huì)為每個(gè)請(qǐng)求創(chuàng)建一個(gè)異步任務(wù)線程,也就是上面我們看到的 MvcAsync 開(kāi)頭的異步任務(wù)線程,那這樣不行啊,開(kāi)銷(xiāo)特別大呀!所以我們可以采用線程池進(jìn)行管理,直接在 WebAsyncTask 類(lèi)構(gòu)造器傳入一個(gè) ThreadPoolTaskExecutor 對(duì)象實(shí)例即可。

下面我們先看看,當(dāng)對(duì)上面第一種情況執(zhí)行并發(fā)請(qǐng)求時(shí)會(huì)出現(xiàn)什么情況(此處模擬對(duì) http://localhost:7000/demo/getUserWithNoThing.json 進(jìn)行并發(fā)調(diào)用):

控制臺(tái)輸出如下:

The first Thread name is MvcAsync57
The first Thread name is MvcAsync58
The first Thread name is MvcAsync59
The first Thread name is MvcAsync60
The first Thread name is MvcAsync61
The first Thread name is MvcAsync62
The first Thread name is MvcAsync63
The first Thread name is MvcAsync64
The first Thread name is MvcAsync65
The first Thread name is MvcAsync66
The first Thread name is MvcAsync67
The first Thread name is MvcAsync68
The first Thread name is MvcAsync69
The first Thread name is MvcAsync70
The first Thread name is MvcAsync71
The first Thread name is MvcAsync72
The first Thread name is MvcAsync73
The first Thread name is MvcAsync74
The first Thread name is MvcAsync76
The first Thread name is MvcAsync75
The first Thread name is MvcAsync77
The first Thread name is MvcAsync78
The first Thread name is MvcAsync79
The first Thread name is MvcAsync80

由于沒(méi)有加入線程池,所以100個(gè)請(qǐng)求將開(kāi)啟100個(gè)異步任務(wù)線程,開(kāi)銷(xiāo)特別大,不推薦。

下面是采用線程池的實(shí)現(xiàn) :

調(diào)用接口 : http://localhost:7000/demo/getUserWithExecutor.json

/**
 * 測(cè)試線程池
 * @return
 */
@RequestMapping(value = "getUserWithExecutor.json", method = RequestMethod.GET)
public WebAsyncTask getUserWithExecutor() {
 System.err.println("The main Thread name is " + Thread.currentThread().getName());
 
 // 此處模擬開(kāi)啟一個(gè)異步任務(wù),此處傳入一個(gè)線程池
 WebAsyncTask task1 = new WebAsyncTask(10 * 1000L, executor, () -> {
 	System.err.println("The first Thread name is " + Thread.currentThread().getName());
 	Thread.sleep(5000L);
 	return "任務(wù)4順利執(zhí)行成功!任何異常都沒(méi)有拋出!";
 });
 
 // 任務(wù)執(zhí)行完成時(shí)調(diào)用該方法
 task1.onCompletion(() -> {
 	System.err.println("任務(wù)4執(zhí)行完成啦!");
 });
 
 System.err.println("task4繼續(xù)處理其他事情!");
 return task1;
}

線程池定義如下:

@Configuration
public class MyExecutor {
 
 @Bean
 public static ThreadPoolTaskExecutor getExecutor() {
 	ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
 	taskExecutor.setCorePoolSize(30);
 	taskExecutor.setMaxPoolSize(30);
 	taskExecutor.setQueueCapacity(50);
 	taskExecutor.setThreadNamePrefix("huang");// 異步任務(wù)線程名以 huang 為前綴
 	return taskExecutor;
 }
}

對(duì)上面進(jìn)行并發(fā)測(cè)試,可以得出下面結(jié)果 :

Spring boot中怎么利用WebAsyncTask實(shí)現(xiàn)異步任務(wù)編程

看完上述內(nèi)容,你們對(duì)Spring boot中怎么利用WebAsyncTask實(shí)現(xiàn)異步任務(wù)編程有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。


本文題目:Springboot中怎么利用WebAsyncTask實(shí)現(xiàn)異步任務(wù)編程
本文網(wǎng)址:http://weahome.cn/article/jjhsoj.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部