Java 在处理请求时使用异步servlet以及dispatch()和complete()方法的行为

Java 在处理请求时使用异步servlet以及dispatch()和complete()方法的行为,java,servlets,asynchronous,concurrency,guava,Java,Servlets,Asynchronous,Concurrency,Guava,我使用异步servlet来处理请求 根据文件:(,) 我不明白它们是如何工作的。对此我几乎没有疑问: async.dispatch()和async.complete()之间到底有什么区别 当我调用dispatch()(insiderun())时,响应到达客户端,这意味着我们可以异步推送响应 如果我先调用asyncContext.dispatch()然后调用asyncContext.complete()下一步线程的行为是什么 如果在asyncContext.complete()之后调用任何方法,该

我使用异步servlet来处理请求

根据文件:(,)

我不明白它们是如何工作的。
对此我几乎没有疑问:

  • async.dispatch()
    async.complete()
    之间到底有什么区别
  • 当我调用dispatch()(insiderun())时,响应到达客户端,这意味着我们可以异步推送响应
  • 如果我先调用
    asyncContext.dispatch()
    然后调用
    asyncContext.complete()
    下一步线程的行为是什么
  • 如果在
    asyncContext.complete()
    之后调用任何方法,该方法调用会发生什么情况,如下面的代码所示(在相同的
    run()
    中)
    [当我测试它时,它工作正常,并且显示相同的线程id]
  • 如果在
    run()
    内部调用异步方法,是否需要在内部完成
    asyncContext.complete()
    ?(onSuccess()或onFailure())
  • 是否有关于此的帮助(示例源代码/书籍/在线帮助)?(异步servlet和未来组合)

    final FutureCallback calculateTime=新客户未来(计算);
    //启动异步上下文。
    final AsyncContext AsyncContext=request.startAsync();
    asyncContext.start(新的Runnable(){
    @凌驾
    公开募捐{
    MyObject对象=null;
    试试{
    object=myFactory.create();
    //调度异步上下文
    asyncContext.dispatch(“已成功创建对象”);
    }捕获(最终IOE1异常){
    logger.error(“记录错误”);
    }
    asyncContext.complete();//完成异步上下文
    //调用异步方法
    final ListenableFuture=myService.doSomething();
    Futures.addCallback(future,calculateTime);
    //在此处调用asyncContext.complete()可以吗?
    }
    });
    
    提前谢谢

  • 从马的嘴里(甲骨文Javadoc) 完成() 完成对用于初始化此AsyncContext的请求启动的异步操作,关闭用于初始化此AsyncContext的响应

    向ServletRequest注册的AsyncListener类型的任何侦听器(为其创建此AsyncContext)都将在其onComplete方法中调用

    分派(字符串路径) 将此AsyncContext的请求和响应对象分派到给定路径

    对请求和响应的控制权委托给调度目标,当调度目标完成执行时,响应将关闭,除非调用ServletRequest#startAsync()或ServletRequest#startAsync(ServletRequest,ServletResponse)

    问答
  • 发送
    完成
    之间有什么区别? 调用
    complete
    告诉容器启动
    onComplete
    侦听器并停止异步模式,
    dispatch
    基本上告诉容器调用
    complete
    ,然后将请求(内部)转发到指定路径。路径可以是JSP、同步servlet,甚至是另一个将触发新一轮异步处理的异步servlet

  • 当我在
    run
    内部调用
    dispatch
    时,响应到达了客户端,这是否意味着我们可以像这样异步推送响应? 相反,
    dispatch
    关闭异步模式并将请求转发给另一个servlet或JSP。要将数据推送到客户端,您必须写入与
    AsyncContext
    关联的
    Response
    对象

  • 如果我先调用
    dispatch
    ,然后调用
    complete
    next,线程的行为是什么? 未定义,这是一种很好的说法,它取决于容器的实现方式。可能它会抛出一个错误,可能
    onComplete
    处理程序会被触发两次,可能调用
    complete
    将一事无成,可能在调用处理程序和操作
    AsyncContext
    实现等的内部结构时,线程和容器之间会存在竞争条件

  • 如果我在
    complete
    之后调用任何方法,该方法调用会发生什么情况 取决于您调用的方法。规范规定,如果在
    complete
    之后调用
    dispatch
    将抛出
    IllegalStateException
    ,则任何其他内容都是未定义的,因此是特定于实现的

  • 如果我在
    run
    内部调用异步方法,我应该调用
    complete
    内部回调()吗? 是的,一旦完成,您必须调用
    complete
    来完成异步处理。
    run
    方法用于计划由容器管理的线程池执行的任务,并且可以在异步请求的生存期内多次调用该方法

  • 有没有使用异步servlet和Futures组合的例子? 我不知道有什么,但在“请参阅”一节中有几个使用异步servlet的好例子。原则上,我认为使用期货没有多大价值。请参阅:“异步servlet是否适合我所做的工作?”

  • 异步servlet是否适合我所做的工作? 异步servlet的目标是减少为某些类型的“推送客户端”提供服务所需的线程数:HTTP请求保持打开状态,直到(通常是外部)事件发生,然后服务器将数据向下推送通道。在标准的servlet环境中,每个客户机将分配一个专用线程并等待,从而消耗宝贵的系统资源。在异步模式下,客户机连接可以“挂起”并与执行线程u分离
    ╔══════════════════╦═══════════════════════════════════════════════════════════╗
    ║ 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.            ║
    ╚══════════════════╩═══════════════════════════════════════════════════════════╝
    
    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?
            }
        });