码迷,mamicode.com
首页 > 其他好文 > 详细

Other - 02 - Servlet学习笔记 - 异步Servlet

时间:2016-01-17 18:57:40      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

异步Servlet

    Servlet默认情况下都是同步的,但是Servlet可以进行异步的调用。

  1. /**
  2. * Servlet implementation class MainServlet
  3. */
  4. @WebServlet(value = "/MainServlet", asyncSupported = true)
  5. public class AsynServlet extends HttpServlet {
  6. private static final long serialVersionUID = 1L;
  7. /**
  8. * Default constructor.
  9. */
  10. public AsynServlet() {
  11. }
  12. /**
  13. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  14. */
  15. @Override
  16. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  17. throws ServletException, IOException {
  18. long startTime = System.currentTimeMillis();
  19. System.out.println("DoGet Start ThreadName = " + Thread.currentThread().getName() + " ThreadId = "
  20. + Thread.currentThread().getId());
  21. AsyncContext asyncCtx = request.startAsync();
  22. asyncCtx.setTimeout(9000);
  23. ExecutorService executorService = (ExecutorService) request.getServletContext().getAttribute("executorService");
  24. executorService.execute(() -> {
  25. try {
  26. System.out.println();
  27. Thread.sleep(5000);
  28. asyncCtx.complete();
  29. } catch (Exception e) {
  30. e.printStackTrace();
  31. }
  32. });
  33. long endTime = System.currentTimeMillis();
  34. System.out.println("doGet End ThreadName = " + Thread.currentThread().getName() + " ThreadId = "
  35. + Thread.currentThread().getId() + " Time = " + (endTime - startTime) + " ms.");
  36. request.getRequestDispatcher("/AnotherServlet").forward(request, response);
  37. }
  38. /**
  39. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  40. */
  41. @Override
  42. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  43. throws ServletException, IOException {
  44. doGet(request, response);
  45. }
  46. }

    异步调用代表当前线程(Tomcat容器线程)到达异步调用处 request.startAsync() 时,会释放掉自己,然后委托另一个业务线程(这里是新建的线程池里的一个业务线程)来完成业务处理,然后调用异步请求的 complete 方法完成异步任务,而 Tomcat 容器线程在异步任务正在执行的过程中会保存起当前任务的状态,一边执行其他的请求,一边等待 complete 的调用,一旦 complete 调用,则异步的请求完成,由原来的 Tomcat 线程完成清理工作,并返回客户端。
    这种模式下,Tomcat 容器线程可以在耗时操作的情况下得到快速的释放并处理新请求,缓解容器线程被占满的情况。

    对于 Long Pool 模型,可以有两种请求模式:
    一种是客户端不断的轮询,根据每一次请求返回的状态进行判断渲染页面,这种方式需要选定合适的轮询周期,否则会导致服务器端计算压力巨大。
    另一种是使用长连接,由服务器 hold 住连接,等待一个事件发生之后让长连接返回客户端,客户端渲染页面,之后客户端在次发起一个长连接,这种方式需要消耗掉服务器大量的资源,需要设置合适的在次连接延迟和连接超时时间。




Other - 02 - Servlet学习笔记 - 异步Servlet

标签:

原文地址:http://www.cnblogs.com/yaowu/p/67ba496f23047ed2fd4728bdc706fec3.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!