摘要:異步處理是指給這些阻塞操作分配一個新線程,并把關(guān)聯(lián)請求處理的線程返回給容器。異步處理支持和的異步處理。在一個上啟用異步處理,設(shè)置注解的參數(shù)為,如下類提供在方法中執(zhí)行異步處理所需的功能。
應(yīng)用服務(wù)器的web容器通常會為每個請求分配一個服務(wù)線程。在重負(fù)載的場景下,容器需要大量的線程去服務(wù)所有客戶端請求。服務(wù)可擴(kuò)展性的限制包括內(nèi)存不足或者耗盡容器線程。創(chuàng)建可擴(kuò)展web程序,你必須確保沒有關(guān)聯(lián)請求的線程是空閑的,所以容器可以使用他們處理新請求。
這里有兩個關(guān)聯(lián)請求的線程空閑的兩個場景:
線程需要在構(gòu)建響應(yīng)之前等待一個資源可用或者處理數(shù)據(jù)。例如,一個應(yīng)用程序需要在構(gòu)建響應(yīng)前查詢數(shù)據(jù)庫或者通過遠(yuǎn)程web服務(wù)訪問數(shù)據(jù)。
線程需要在構(gòu)建響應(yīng)之前等待一個事件。例如,線程在構(gòu)建響應(yīng)之前需要等待一個JMS消息,另一個客戶端的新信息,或者隊(duì)列里面的新數(shù)據(jù)可用。
這些場景代表限制web程序可擴(kuò)展性的阻塞操作。異步處理是指給這些阻塞操作分配一個新線程,并把關(guān)聯(lián)請求處理的線程返回給web容器。
servlet 異步處理java ee支持servlet和filter的異步處理。如果一個servlet或一個filter處理請求時可能到達(dá)一個阻塞操作,它可以把操作分配給一個異步處理上下文并且在不生成響應(yīng)的情況下將關(guān)聯(lián)請求處理的線程回送給web容器。阻塞操作在不同線程的異步上下文中執(zhí)行完成,它可以生成響應(yīng)或者轉(zhuǎn)發(fā)請求到另一個servlet。
在一個servlet上啟用異步處理,設(shè)置@WebServlet注解的asyncSupported參數(shù)為true,如下:
@WebServlet(urlPatterns={"/asyncservlet"}, asyncSupported=true) public class AsyncServlet extends HttpServlet { ... }
javax.servlet.AsyncContext類提供在Service方法中執(zhí)行異步處理所需的功能。獲得一個AsyncContext實(shí)例,在service方法中調(diào)用request對象的startAsync()方法;例如:
public void doGet(HttpServletRequest req, HttpServletResponse resp) { ... AsyncContext acontext = req.startAsync(); ... }
這個調(diào)用將請求進(jìn)入異步模式并且確保響應(yīng)在退出service方法時每月被提交。你必須在異步上下文完成阻塞操作時生成響應(yīng)或者轉(zhuǎn)發(fā)到其他servlet中。
AsyncContext類提供的基礎(chǔ)功能描述:
方法簽名:void start(Runnable run)
描述:容器提供的能提供阻塞操作處理的不同線程
方法簽名:ServletRequest getRequest()
描述:返回用來初始化異步上下文的請求。在上面的例子中,request與service方法中的相同。你可以通過這個方法在異步上下文中從請求中獲取參數(shù)。
方法簽名:ServletResponse getResponse()
描述:返回初始化異步上下文的響應(yīng)。在上面的例子中,response與service方法中的相同。你可以在異步上下文中,使用這個方法寫入阻塞操作的結(jié)果到響應(yīng)中。
方法簽名:void complete()
描述:完成異步操作,并關(guān)閉與此異步上下文關(guān)聯(lián)的響應(yīng)。你可以在異步上下文完成寫入響應(yīng)后調(diào)用這個操作。
方法簽名:void dispatch(String path)
描述:轉(zhuǎn)發(fā)請求和響應(yīng)到給定的路徑。在阻塞操作完成后,使用這個方法調(diào)用另一個servlet寫出響應(yīng)。
這個章節(jié)示范了怎么使用AsyncContext上下文提供的功能,有如下用例:
servlet從一個GET請求中獲取參數(shù)
servlet使用一個資源,比如一個數(shù)據(jù)庫或者一個web service,基于這個參數(shù)獲取信息。這個資源可能比較緩慢,所以這可能是一個阻塞操作。
servlet使用資源的結(jié)果生成響應(yīng)。
下面的例子是一個不使用異步處理的常見servlet:
@WebServlet(urlPatterns={"/syncservlet"}) public class SyncServlet extends HttpServlet { private MyRemoteResource resource; @Override public void init(ServletConfig config) { resource = MyRemoteResource.create("config1=x,config2=y"); } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/html;charset=UTF-8"); String param = request.getParameter("param"); String result = resource.process(param); /* ... print to the response ... */ } }
下面的示例是同一個servlet,但使用了異步處理:
@WebServlet(urlPatterns={"/asyncservlet"}, asyncSupported=true) public class AsyncServlet extends HttpServlet { /* ... Same variables and init method as in SyncServlet ... */ @Override public void doGet(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/html;charset=UTF-8"); final AsyncContext acontext = request.startAsync(); acontext.start(new Runnable() { public void run() { String param = acontext.getRequest().getParameter("param"); String result = resource.process(param); HttpServletResponse response = acontext.getResponse(); /* ... print to the response ... */ acontext.complete(); } }
AsyncServlet在@WebServlet注解屬性中添加asyncSupported=true。其余的差異在service方法中:
request.startAsync() 引發(fā)request被異步執(zhí)行;response不會在service方法結(jié)束時發(fā)送到客戶端;
acontext.start(new Runnable() {...})從容器中得到一個新的線程。
內(nèi)部類中的run() 中的代碼在一個新線程中執(zhí)行。內(nèi)部類需要從異步上下文中讀取請求參數(shù)和寫入響應(yīng)。調(diào)用異步上下文的complete()方法來提交并發(fā)送響應(yīng)到客戶端。
AsyncServlet的service方法立即返回,同時請求在異步上下文中處理。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74257.html
摘要:調(diào)用棧被清空,消息隊(duì)列中并無任務(wù),線程停止,事件循環(huán)結(jié)束。不確定的時間點(diǎn)請求返回,將設(shè)定好的回調(diào)函數(shù)放入消息隊(duì)列。調(diào)用棧執(zhí)行完畢執(zhí)行消息隊(duì)列任務(wù)。請求并發(fā)回調(diào)函數(shù)執(zhí)行順序無法確定。 異步編程 JavaScript中異步編程問題可以說是基礎(chǔ)中的重點(diǎn),也是比較難理解的地方。首先要弄懂的是什么叫異步? 我們的代碼在執(zhí)行的時候是從上到下按順序執(zhí)行,一段代碼執(zhí)行了之后才會執(zhí)行下一段代碼,這種方式...
摘要:本部分示例見這個項(xiàng)目的分支下的中引進(jìn)了基于異步請求處理的。同時主容器線程退出釋放并允許處理其他請求。對的調(diào)用返回,可以被用于異步處理之上的進(jìn)一步控制。 ??本部分示例見這個項(xiàng)目的 mvc 分支下的 AsyncController.java ??Spring MVC 3.2 中引進(jìn)了基于異步請求處理的 Servlet 3。除了返回一個值,一個控制器方法現(xiàn)在可以返回一個java.util...
摘要:概述本篇主要介紹的運(yùn)行機(jī)制單線程事件循環(huán)結(jié)論先在中利用運(yùn)行至完成和非阻塞完成單線程下異步任務(wù)的處理就是先處理主模塊主線程上的同步任務(wù)再處理異步任務(wù)異步任務(wù)使用事件循環(huán)機(jī)制完成調(diào)度涉及的內(nèi)容有單線程事件循環(huán)同步執(zhí)行異步執(zhí)行定時器的事件循環(huán)開始 1.概述 本篇主要介紹JavaScript的運(yùn)行機(jī)制:單線程事件循環(huán)(Event Loop). 結(jié)論先: 在JavaScript中, 利用運(yùn)行至...
摘要:微信官方?jīng)]有給出來處理異步操作,而官方異步的又非常多,這使得多異步編程會層層回調(diào),代碼一復(fù)雜,回調(diào)起來就想砸電腦。是一個轉(zhuǎn)換微信小程序異步為的一個工具庫優(yōu)點(diǎn)避免小程序異步編程多次回調(diào)帶來的過多回調(diào)導(dǎo)致邏輯不清晰,篇幅過長等問題。 把微信小程序異步API轉(zhuǎn)化為Promise。用Promise處理異步操作有多方便,誰用誰知道。微信官方?jīng)]有給出Promise API來處理異步操作,而官方AP...
閱讀 866·2023-04-26 00:11
閱讀 2666·2021-11-04 16:13
閱讀 2116·2021-09-09 09:33
閱讀 1483·2021-08-20 09:35
閱讀 3836·2021-08-09 13:42
閱讀 3615·2019-08-30 15:55
閱讀 1074·2019-08-30 15:55
閱讀 2228·2019-08-30 13:55