Servlet 3.0中AsyncContext.start(...)的用途是什么?

Aiv*_*var 19 servlets servlet-3.0

Servlet API说"AsyncContext.start":

void start(java.lang.Runnable run)

使容器可能从托管线程池调度线程,以运行指定的Runnable.容器可以将适当的上下文信息传播到Runnable.

从该描述中不清楚当作业需要等待时它如何与优化线程使用的任务相关.

在"Servlet和JSP"中,Budi Kurniawan给出了Servlet 3.0异步功能的例子,在他使用的地方AsyncContext.start,我将展示示例的简化版本:

public void doGet(...) {
    final AsyncContext asyncContext = request.startAsync();

    asyncContext.start(new Runnable() {                        
        @ Override
        public void run() {
            // do some work here which involves waiting
            ...
            asyncContext.complete();
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

在我遇到的大多数其他示例中,服务方法只是将AsyncContext存储在某处,并在其他地方处理(例如,通过后台线程).在这个例子中,它似乎只是将作业传递给另一个完成请求的线程.据我所知,现在它只是工作线程,浪费时间等待.

你是否通过将工作(涉及等待)从一个线程传递到另一个线程来获得某些东西?如果没有,那么目的是AsyncContext.start(...)什么?

Tom*_*icz 14

你发现了一个糟糕的例子,恕我直言.事实上,我甚至都不知道AsyncContext.start()存在.

我快速了解了JettyTomcat如何实现这一点.实际上,它们似乎有一些独立处理异步调用的线程池.

这种API的使用不会给你带来任何东西或很少.而不是阻止HTTP线程,你阻止了一些其他线程池.所以我可以想象应用程序仍然接受新连接,但问题仍然存在 - 容器无法处理它们,因为额外的线程池仍然有限.

整个要点AsyncContext是能够通过单个线程处理多个请求.通常,您只需要一个线程来处理数千个异步连接 - 例如,当只有一个线程等待假设要向多个客户端广播的数据时.另请参阅AsyncContext.start()的有限实用性


Joh*_*nis 10

起初我有同样的反应 - 如果你只是把工作交给另一个线程,你会得到什么?该规范对解释为什么这是一个好主意没有多大帮助.但这篇文章做得很好.基本上,它是让服务器在高负载下正常降级而不是因为线程耗尽而失败.实际工作是在固定大小的线程池中完成的,因此服务器可以接受任意数量的请求,而不必为每个请求保留一个线程,直到完成为止.当然,您可能需要调整O/S设置才能一次打开数千个套接字.

一旦掌握了这种能力,您就可以更轻松地利用Comet(服务器推送)架构,客户端Javascript保持AJAX请求打开,以便服务器可以在某些事件发生时立即通知它,而不必轮询服务器找出是否发生了什么事.