首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Servlet 3的异步Servlet特性--如何处理耗时的任务

Servlet 3的异步Servlet特性--如何处理耗时的任务
EN

Stack Overflow用户
提问于 2014-06-04 06:20:08
回答 1查看 1.1K关注 0票数 2

这些天我正在学习Servlet3.0异步特性,它的主要思想是释放绑定到Http线程到另一个线程的任务,这样Http线程可以返回到Http线程池(而不是阻塞长任务处理),这样您的应用程序就可以更快地响应。这里一切都很好。

我找到了两种方法来处理这个耗时的任务

  1. acontext.start() asyncContext.start(new (){ @Override (){ serviceImpl(req,resp,adapter,context,isNotLeakScan);}); 官方医生说:acontext.start(new Runnable() {...}) gets a new thread from the container.
  2. 使用BlockingQueue,然后使用新的处理队列中的runnables的步骤。 私有静态最终BlockingQueue队列=新LinkedBlockingQueue();线程=新线程(新Runnable() { @Override ()){ while (true) { try (True){ try { Thread.sleep(2000);AsyncContext context;while (context= queue.poll()) != null) {try{ ServletResponse response = context.getResponse();response.setContentType(“text/平原”);PrintWriter out = response.getWriter();Out.printf(“线程%s完成了任务”),Thread.currentThread().getName();out.flush();} catch (异常e) {抛出新的RuntimeException(e.getMessage(),e);}最后{ context.complete();}} catch (InterruptedException e) {返回;}} }

我的问题是:

  • 这两种方法有什么区别?
  • 第一个是否将任务管理处理到Tomcat容器(假设我们已经在Tomcat上部署了应用程序)
  • 第二种方式只是显示了手动处理任务的方式?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-04 08:35:16

不同之处在于:

(1)在servlet线程池中执行缓慢的任务,导致servlet池饥饿(至少Tomcat/Jetty是这样的)。这意味着,如果用serviceImpl(req, resp, adapter, context, isNotLeakScan);替换Thread.sleep(Long.MAX_VALUE);,并尝试从浏览器连接Tomcat 200次(默认线程数为200个),那么Tomcat将永远挂起,不再接受任何HTTP连接。

(2)手工生成每个任务的线程。

您通常不希望手动生成线程、轮询队列等。相反,您可以使用Executors框架,它在外壳下具有队列实现,并且基于内部线程池。

代码语言:javascript
复制
@WebServlet(urlPatterns = {"/slowServlet"}, asyncSupported = true)
public class SlowServlet extends javax.servlet.http.HttpServlet {

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        final AsyncContext acontext = request.startAsync();
        ServletContext appScope = request.getServletContext();
        ((Executor) appScope.getAttribute("executor")).execute(() -> {
            try {
                Thread.sleep(10000); // your slow running task
                acontext.getResponse().getWriter().print("Done");
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
}

servlet上下文侦听器是(线程池的大小在这里是硬编码的)

代码语言:javascript
复制
@WebListener
public class ExecutorListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent sce) {
        Executor executor = Executors.newFixedThreadPool(10);
        sce.getServletContext().setAttribute("executor", executor);
    }

    public void contextDestroyed(ServletContextEvent sce) {
        // add executor fancy shutdown logic here
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24030366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档