使用异步Servlet和派遣()和完整的()方法的行为,而处理请求 [英] Using Asynchronous Servlets and the behaviour of dispatch() and complete() methods while processing request
问题描述
我使用的异步servlet来处理请求,
<$p$p><$c$c>╔══════════════════╦═══════════════════════════════════════════════════════════╗║无效完成()║完成异步操作并关闭║
║║与此异步上下文关联的响应。 ║
║║你写入响应对象后调用此方法║
║异步上下文中║。 ║
╠══════════════════╬═══════════════════════════════════════════════════════════╣
║无效讯()║调度请求和响应对象║
║║这AsyncContext到servlet容器中。 ║
╚══════════════════╩═══════════════════════════════════════════════════════════╝
我不明白异步。调度(),异步.complete(),以及它们如何工作
的我对此有一些疑虑:
- 什么
之间async.dispatch()完全相同的差异
和async.complete()
? - 当我打电话给调度()(里面的run())的响应到达客户端,这意味着我们可以异步推回应?
- 如果我称之为
asyncContext.dispatch()
第一和asyncContext.complete()
接下来是什么行为线程? - 如果我打电话后,任何方法
asyncContext.complete()
,会发生什么是方法调用,如下图所示code(在相同的运行()
)?
[当我测试这个它的正常工作,并显示出相同的线程ID] - 如果我打电话里面
异步方法的run()
我应该需要完成asyncContext.complete()
内<一href=\"http://docs.guava-libraries.google$c$c.com/git/javadoc/com/google/common/util/concurrent/Futures.html#addCallback%28com.google.common.util.concurrent.ListenableFuture,%20com.google.common.util.concurrent.FutureCallback%29\"相对=nofollow>回调()? (的onSuccess()或者onFailure处()) -
无论任何帮助(例如源/书籍/联机帮助)提供有关本? (异步Servlet和期货组合)
最后FutureCallback&LT;无效&GT; calculateTime =新CustomFuture&LT;&GT;(计算);
//启动异步上下文。
最终AsyncContext asyncContext = request.startAsync(); asyncContext.start(新的Runnable(){
@覆盖
公共无效的run(){ MYOBJECT对象= NULL;
尝试{
对象= myFactory.create();
//调度异步上下文
asyncContext.dispatch(对象创建成功);
}赶上(最终IOException异常E1){
logger.error(记录错误);
}
asyncContext.complete(); //完整的背景下异步 //调用异步方法
最后ListenableFuture&LT;无效&GT;未来= myService.doSomething(); Futures.addCallback(未来,calculateTime);
//调用asyncContext.complete()在这里是否行得通呢?
}
});先谢谢了。
从马的嘴(甲骨文的Javadoc)
完成()
完成对启动上用于initialze这个AsyncContext的要求,关闭被用于初始化这个AsyncContext的响应异步操作。
这是与创建此AsyncContext将在他们的onComplete方法被调用的ServletRequest注册类型AsyncListener的任何侦听器。
讯(字符串路径)
调度此AsyncContext给定路径的请求和响应的对象。
...
在请求控制和响应委托给调度目标,当目标调度执行完毕的响应将被关闭,除非的ServletRequest#startAsync()或ServletRequest中#startAsync(的ServletRequest,ServletResponse的)被调用。
Q / A
-
什么的区别
调度
和完整
?调用
完整
告诉容器以的onComplete
听众和停止异步模式下,调度
基本上告诉容器调用完整
,然后将请求转发(内部)到指定的路径。路径可以是一个JSP,同步servlet或甚至另一个异步的servlet,这将引发新一轮的异步处理的。 -
当我打电话
调度
在运行
响应到达客户端,这是否意味着我们可以把响应异步这样?相反
关联对象LI>调度
关闭asynchrnonous模式,将请求转发到另一个servlet或JSP。为了将数据推送到你写响应客户端
与AsyncContext
。 -
如果我叫
调度
第一和完整
接下来是什么线程的行为?不定,这是说的一个很好的方式,它取决于容器是如何实现的。也许它会抛出一个错误,也许
的onComplete
处理程序将被两次开除,也许来电完整
会做什么,也许会有你的线程,并呼吁处理程序和操纵AsyncContext
实施等内部结构的容器之间的竞争条件。 -
如果我打电话后,任何方法
完整
会发生这种方法叫什么取决于你正在调用什么方法。该规范规定
调度
将抛出IllegalStateException异常
后,如果称为完全
,别的是不确定的,因此具体执行。 -
如果我打电话
运行里面的异步方法
我应该叫完整
里面的回调()<? / H3>是你要调用
完整
一旦你完成完成异步处理。在运行
方法用于计划任务由一个容器管理的线程池来执行,它可以被多次调用异步请求的生命周期中。 -
是否有
使用异步Servlet和期货组合的例子吗?我不知道任何,但也有使用参见部分挂钩异步的servlet的一些很好的例子。原则上我看不出使用期货多大价值。请参见:是异步的servlet非常适合我在做什么
是异步的servlet非常适合我在做什么?
异步Servlet的目标是减少对服务于某些类型的推客户端的所需线程数:HTTP直到一个(通常是外部的)事件发生时,请求被保持打开,然后服务器将数据推走在信道。在一个标准的servlet环境中的每个客户都会有一个专门的线程分配,并等待从而节省宝贵的系统资源。在异步模式中,客户端连接可以直到一个事件进来,这使得它能够用它做什么放在暂停和拆卸从执行线程。想想一个在线聊天应用程序为例。所有连接的客户端将被闲置,直到有人将消息放到了房间。这是一种浪费,保持一个专用的线程为每个连接的用户。
如果您的应用程序需要同时调用多个服务,并要使用期货和执行人并行的操作,然后异步的servlet可能不是一个很好的配合:你将一无所获和标准的servlet会容易得多实现。如果对服务呼叫可以在异步(非阻塞)的方式进行,不依赖于螺纹执行人另一方面,则又是另一回事。
正确的问题要问的是:我想有比活动连接线程较少的
另请参阅:
- 在状态图
AsyncStateMachine
的javadoc(Tomcat的实现)。 - 的https://blogs.oracle.com/enterprisetechtips/entry/asynchronous_support_in_servlet_3
- Servlet-3异步背景下,如何做异步写入?
I am using Asynchronous Servlets to process requests,
According to Docs:(complete(),dispatch())
╔══════════════════╦═══════════════════════════════════════════════════════════╗
║ void complete() ║ Completes the asynchronous operation and closes the ║
║ ║ response associated with this asynchronous context. ║
║ ║ You call this method after writing to the response object ║
║ ║ inside the asynchronous context. ║
╠══════════════════╬═══════════════════════════════════════════════════════════╣
║ void dispatch() ║ Dispatches the request and response objects ║
║ ║ of this AsyncContext to the servlet container. ║
╚══════════════════╩═══════════════════════════════════════════════════════════╝
I failed to understand async.dispatch(), async.complete(), and how they work.
I have few doubts on this:
- What exactly the difference between
async.dispatch()
andasync.complete()
? - When I called dispatch()(inside run()) the response reaches the client, that mean we can push the response asynchronously?
- if I call
asyncContext.dispatch()
first andasyncContext.complete()
next what is the behaviour of the thread? - If I call any method after
asyncContext.complete()
, what will happen to that method call, as shown below code(in the samerun()
)?
[when I tested this it's working fine and showing same thread id] - If I am calling Asynchronous methods inside
run()
should I need to completeasyncContext.complete()
inside callback()? (onSuccess() or onFailure()) Whether any help(example source/books/online help) available regarding this? (Async Servlets and Futures Combination)
final FutureCallback<Void> calculateTime= new CustomFuture<>(calculate); // start Async context. final AsyncContext asyncContext = request.startAsync(); asyncContext.start(new Runnable() { @Override public void run() { MyObject object= null; try { object= myFactory.create(); //dispatch async context asyncContext.dispatch("Object Successfully Created"); } catch (final IOException e1) { logger.error("logging error"); } asyncContext.complete(); //complete async context // call asynchronous method final ListenableFuture<Void> future = myService.doSomething(); Futures.addCallback(future, calculateTime); // calling asyncContext.complete() here will work? } });
Thanks in Advance.
From the horse's mouth (Oracle Javadoc)
complete()
Completes the asynchronous operation that was started on the request that was used to initialze this AsyncContext, closing the response that was used to initialize this AsyncContext.
Any listeners of type AsyncListener that were registered with the ServletRequest for which this AsyncContext was created will be invoked at their onComplete method.
dispatch(String path)
Dispatches the request and response objects of this AsyncContext to the given path.
...
Control over the request and response is delegated to the dispatch target, and the response will be closed when the dispatch target has completed execution, unless ServletRequest#startAsync() or ServletRequest#startAsync(ServletRequest, ServletResponse) are called.
Q/A
what's the difference between
dispatch
andcomplete
?Calling
complete
tells container to fireonComplete
listeners and stop the asynchronous mode,dispatch
basically tells container to callcomplete
and then forward the request (internally) to the specified path. The path can be a JSP, a synchronous servlet or even another asynchronous servlet that will trigger a new round of async processing.When I called
dispatch
insiderun
the response reached the client, does that mean we can push the response asynchronously like this?On the contrary
dispatch
closes the asynchrnonous mode and forwards the request to another servlet or JSP. To push data to the client you have to write toResponse
object associated with theAsyncContext
.if I call
dispatch
first andcomplete
next what is the behaviour of the thread ?Undefined, which is a nice way of saying it depends on how the container is implemented. Maybe it will throw an error, maybe
onComplete
handlers will be fired twice, maybe call tocomplete
will do nothing, maybe there will be a race condition between your thread and the container in calling handlers and manipulating internal structures ofAsyncContext
implementation etc.If I call any method after
complete
what will happen to that method callDepends on what method you are calling. The specification states that
dispatch
will throwIllegalStateException
if called aftercomplete
, anything else is undefined and thus implementation specific.If I am calling asynchronous methods inside
run
should I callcomplete
inside callback()?Yes you have to call
complete
to finish asynchronous processing once you are done. Therun
method is used to schedule a task to be executed by a container managed thread pool and it can be called multiple times during the lifetime of an asynchronous request.Are there any examples of using Async Servlets and Futures Combination?
I am not aware of any, but there are a few good examples of using async servlets linked in "See also" section. In principle I don't see much value in using futures. See: "Is async servlet a good fit for what I am doing?"
Is async servlet a good fit for what I am doing ?
The objective of an async servlet is to reduce the number of threads required to serve certain types of "push clients": HTTP request is left open until an (usually external) event occurs and then the server will push data down the channel. In a standard servlet environment each client will have a dedicated thread allocated and waiting thus consuming valuable system resources. In asynchronous mode the client connection can be put "on hold" and detached from an execution thread until an event comes in which makes it possible to do something with it. Think about an online chat application as an example. All connected clients will be idle until someone posts a message to the room. It is wasteful to keep a dedicated thread for every connected user.
If your application needs to call multiple services at the same time and you wish to use futures and executors to parallelize that operation then an asynchronous servlet is probably not a good fit: You will gain nothing and a standard servlet will be much easier to implement. On the other hand if service calls can be made in an asynchronous (non-blocking) way, without relying on threaded executors, then it's another story.
The "right" question to ask is: Do I want to have fewer threads than active connections?
See also:
- A state diagram in
AsyncStateMachine
javadoc (Tomcat implementation). - https://blogs.oracle.com/enterprisetechtips/entry/asynchronous_support_in_servlet_3
- Servlet-3 Async Context, how to do asynchronous writes?
这篇关于使用异步Servlet和派遣()和完整的()方法的行为,而处理请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!