可能重复一次!我使用Tomcat作为我的服务器,并想知道什么是在确定性结果的servlet中生成线程的最佳方法.我正在从servlet操作运行一些长时间运行的更新,并希望完成请求并在后台进行更新.而不是添加像RabbitMQ这样的消息中间件,我想我可以生成一个可以在后台运行并在自己的时间内完成的线程.我在其他SO线程中读到服务器终止服务器生成的线程,以便它能够很好地管理资源.
在使用Tomcat时是否有推荐的方法来生成线程,后台作业.我还使用Spring MVC作为应用程序.
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(...)
什么?
我创建了一个servlet 3.0来探索异步请求处理:
@WebServlet(name="MyTest", urlPatterns={"/MyTest"}, asyncSupported=true)
public class MyTest extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
AsyncContext tmp = req.startAsync(req, res);
...
}
}
Run Code Online (Sandbox Code Playgroud)
但我得到的IllegalStateException
时候.startAsync(...)
被调用.我知道Javadoc提到了异常,但我明确地启用了异步(cf WebServlet
annotation).我正在使用随NetBeans提供的Tomcat 7.0.11.0.
我可以确认这req.isAsyncSupported()
是假的.我究竟做错了什么?我还需要做些什么来启用异步处理?
编辑:
我试图实现以下示例并得到相同的问题.
java ×2
servlet-3.0 ×2
servlets ×2
asynchronous ×1
process ×1
request ×1
spring-mvc ×1
tomcat ×1