Cha*_*har 10 java concurrency asynchronous servlets guava
我正在使用异步Servlet来处理请求,
根据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. ?
????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
我无法理解async.dispatch(),async.complete()及其工作原理.
我对此几乎没有疑问:
async.dispatch()
和async.complete()
?asyncContext.dispatch()
先调用asyncContext.complete()
,那么线程的行为是什么?asyncContext.complete()
,该方法调用会发生什么,如下所示代码(在同一个中run()
)? run()
我是否需要完成asyncContext.complete()
内部回调()?(onSuccess()或onFailure())是否有任何关于此的帮助(示例来源/书籍/在线帮助)?(异步Servlet和期货组合)
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?
}
});
Run Code Online (Sandbox Code Playgroud)
提前致谢.
ant*_*tix 16
完成在用于初始化此AsyncContext的请求上启动的异步操作,关闭用于初始化此AsyncContext的响应.
任何类型为AsyncListener的侦听器都将在其onComplete方法中调用,这些侦听器是为创建此AsyncContext的ServletRequest注册的.
将此AsyncContext的请求和响应对象调度到给定路径.
...
对请求和响应的控制被委托给调度目标,并且在调度目标完成执行时将关闭响应,除非调用ServletRequest#startAsync()或ServletRequest #startAsync(ServletRequest,ServletResponse).
dispatch
和之间有什么区别complete
?调用complete
告诉容器触发onComplete
侦听器并停止异步模式,dispatch
基本上告诉容器调用complete
然后将请求(内部)转发到指定路径.该路径可以是JSP,同步servlet,甚至是另一个将触发新一轮异步处理的异步servlet.
dispatch
在内部调用run
响应到达客户端时,这是否意味着我们可以像这样异步推送响应?相反,dispatch
关闭异步模式并将请求转发给另一个servlet或JSP.要将数据推送到客户端,您必须写入Response
与之关联的对象AsyncContext
.
dispatch
先调用complete
,那么线程的行为是什么?未定义,这是一种很好的说法,取决于容器的实现方式.也许它会抛出一个错误,也许onComplete
处理程序会被触发两次,也许会调用complete
什么也不做,也许你的线程和容器之间会有一个竞争条件,在调用处理程序和操作内部结构的AsyncContext
实现等.
complete
会发生什么是方法调用取决于你打电话的方法.规范声明如果调用后将dispatch
抛出,其他任何未定义的特定实现.IllegalStateException
complete
run
应该complete
在callback()内调用?是的,complete
一旦完成,你必须调用完成异步处理.该run
方法用于调度由容器管理的线程池执行的任务,并且可以在异步请求的生存期内多次调用它.
我不知道,但在"另请参阅"部分中有一些使用异步servlet链接的好例子.原则上我认为使用期货没什么价值.请参阅:"async servlet是否适合我正在做的事情?"
异步servlet的目标是减少为某些类型的"推送客户端"提供服务所需的线程数:HTTP请求保持打开状态,直到发生(通常是外部)事件,然后服务器将数据推送到通道.在标准的servlet环境中,每个客户端将分配一个专用线程并等待,从而消耗宝贵的系统资源.在异步模式下,客户端连接可以"保持"并从执行线程中分离,直到事件发生,从而可以对其执行某些操作.以在线聊天应用程序为例.所有连接的客户端将处于空闲状态,直到有人向房间发送消息.为每个连接的用户保留专用线程是浪费的.
如果您的应用程序需要同时调用多个服务,并且您希望使用期货和执行程序来并行化该操作,那么异步servlet可能不太合适:您将无法获得任何东西,并且标准servlet将更容易实现.另一方面,如果服务调用可以以异步(非阻塞)方式进行,而不依赖于线程执行程序,那么这是另一个故事.
要问的"正确"问题是:我是否希望拥有比活动连接更少的线程?
也可以看看:
AsyncStateMachine
javadoc中的状态图(Tomcat实现).