{"id":18014,"date":"2013-10-13T15:00:10","date_gmt":"2013-10-13T12:00:10","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=18014"},"modified":"2013-10-11T14:39:55","modified_gmt":"2013-10-11T11:39:55","slug":"how-to-use-asynchronous-servlets-to-improve-performance","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html","title":{"rendered":"How to use Asynchronous Servlets to improve performance"},"content":{"rendered":"<p>This post is going to describe a performance optimization technique applicable to a common problem related to modern webapps. Applications nowadays are no longer just passively waiting for browsers to initiate requests, but want to start the communication themselves. A typical example could involve chat applications, auction houses, etc \u2013 the common denominator being the fact that most of the time the connections with the browser are idle and wait for a certain event being triggered.<\/p>\n<p>This type of applications have developed a problem class of their own, especially when facing heavy load. The symptoms include starving threads, suffering user interaction, staleness issues, etc.<\/p>\n<p>Based on recent experience with this type of apps under load, I thought it would be a good time to demonstrate a simple solution. After Servlet API 3.0 implementations became mainstream, the solution has become truly simple, standardized and elegant.<\/p>\n<p>But before we jump into demonstrating the solution, we should understand the problem in more details. For our readers \u2013 what could be easier than to explain the problem with help of some source code:<\/p>\n<pre class=\" brush:java\">@WebServlet(urlPatterns = \"\/BlockingServlet\")\r\npublic class BlockingServlet extends HttpServlet {\r\n  private static final long serialVersionUID = 1L;\r\n\r\n  protected void doGet(HttpServletRequest request,\r\n                       HttpServletResponse response) throws ServletException, IOException {\r\n    try {\r\n      long start = System.currentTimeMillis();\r\n      Thread.sleep(2000);\r\n      String name = Thread.currentThread().getName();\r\n      long duration = System.currentTimeMillis() - start;\r\n      response.getWriter().printf(\"Thread %s completed the task in %d ms.\", name, duration);\r\n    } catch (Exception e) {\r\n      throw new RuntimeException(e.getMessage(), e);\r\n    }\r\n  }<\/pre>\n<p>The servlet above is an example of how an application described above could look like:<\/p>\n<ul>\n<li>Request arrives, announcing interest to monitor certain events<\/li>\n<li>The thread is blocked until the event arrives<\/li>\n<li>Upon receiving the event, the response is compiled and sent back to the client<\/li>\n<\/ul>\n<p>In order to keep it simple, we have replaced the waiting part with a call to <em>Thread.sleep()<\/em>.<\/p>\n<p>Now \u2013 this is a perfectly normal servlet you might think. In many cases, you are completely correct \u2013 there is nothing wrong with the code until the application faces significant load.<\/p>\n<p>In order to simulate this load I created a fairly simple test with some help from <a href=\"http:\/\/jmeter.apache.org\/\">JMeter,<\/a> where I launched 2,000 threads, each running through 10 iterations of bombarding the application with requests to the <em>\/BlockedServlet<\/em>. Running the test with the deployed servlet on an out-of-the-box <a href=\"http:\/\/apache.tomcat.org\">Tomcat 7.0.42<\/a> I got the following results:<\/p>\n<ul>\n<li><strong>Average response time: 19,324 ms<\/strong><\/li>\n<li>Minimum response time: 2,000 ms<\/li>\n<li>Maximum response time: 21,869 ms<\/li>\n<li><strong>Throughput: 97 requests\/second<\/strong><\/li>\n<\/ul>\n<p>The default Tomcat configuration has got 200 worker threads which, coupled with the fact that the simulated work is replaced with 2,000ms sleep cycle explains nicely the minimum and maximum response times \u2013 in each second the 200 threads should be able to complete 100 sleep cycles, 2 seconds each. Adding context switch costs on top of this, the achieved throughput of 97 requests\/second is pretty close to our expectations.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>The throughput itself would not look too bad for 99.9% of the applications out there. Looking at the maximum and especially, average response times the problem starts to look more serious though. Getting the response in 20 seconds instead of expected 2 seconds is a sure way to annoy your users.<\/p>\n<p>Let us now take a look at an alternative implementation, taking advantage of the Servlet API 3.0 asynchronous support:<\/p>\n<pre class=\" brush:java\">@WebServlet(asyncSupported = true, value = \"\/AsyncServlet\")\r\npublic class AsyncServlet extends HttpServlet {\r\n  private static final long serialVersionUID = 1L;\r\n\r\n  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\r\n    Work.add(request.startAsync());\r\n  }\r\n}<\/pre>\n<pre class=\" brush:java\">public class Work implements ServletContextListener {\r\n  private static final BlockingQueue queue = new LinkedBlockingQueue();\r\n\r\n  private volatile Thread thread;\r\n\r\n  public static void add(AsyncContext c) {\r\n    queue.add(c);\r\n  }\r\n\r\n  @Override\r\n  public void contextInitialized(ServletContextEvent servletContextEvent) {\r\n    thread = new Thread(new Runnable() {\r\n      @Override\r\n      public void run() {\r\n        while (true) {\r\n          try {\r\n            Thread.sleep(2000);\r\n            AsyncContext context;\r\n            while ((context = queue.poll()) != null) {\r\n              try {\r\n                ServletResponse response = context.getResponse();\r\n                response.setContentType(\"text\/plain\");\r\n                PrintWriter out = response.getWriter();\r\n                out.printf(\"Thread %s completed the task\", Thread.currentThread().getName());\r\n                out.flush();\r\n              } catch (Exception e) {\r\n                throw new RuntimeException(e.getMessage(), e);\r\n              } finally {\r\n                context.complete();\r\n              }\r\n            }\r\n          } catch (InterruptedException e) {\r\n            return;\r\n          }\r\n        }\r\n      }\r\n    });\r\n    thread.start();\r\n  }\r\n\r\n  @Override\r\n  public void contextDestroyed(ServletContextEvent servletContextEvent) {\r\n    thread.interrupt();\r\n  }\r\n}<\/pre>\n<p>This bit of code is a bit more complex, so maybe before we start digging into solution details, I can outline that this solution performed <strong>~75x better latency- and ~20x better throughput-wise<\/strong>. Equipped with knowledge of such results, you should be more motivated to understand what is actually going on in the second example.<\/p>\n<p>The servlet itself looks truly simple. Two facts are worth outlining though, first of which declares the servlet to support asynchronous method invocations:<\/p>\n<pre class=\" brush:java\">@WebServlet(asyncSupported = true, value = \"\/AsyncServlet\")<\/pre>\n<p>Second important aspect is hidden in the following line<\/p>\n<pre class=\" brush:java\">Work.add(request.startAsync());<\/pre>\n<p>in which the whole request processing is delegated to the <em>Work<\/em> class. The context of the request is stored using an <em>AsyncContext<\/em> instance holding the request and response that were provided by the container.<\/p>\n<p>Now, the second and more complex class \u2013 the <em>Work<\/em> implemented as <em>ServletContextListener<\/em> starts looking simpler. Incoming requests are just queued in the implementation to wait for the notification \u2013 this could be an updated bid on the monitored auction or the next message in the group chat that all the requests are waiting for.<\/p>\n<p>When the notification arrives \u2013 again, simplified as just waiting 2,000ms in a <em>Thread.sleep()<\/em>, all the blocked tasks in the queue are processed by a single worker thread responsible for compiling and sending the responses. Instead of blocking hundreds of threads to wait behind the external notification, we achieved this in a lot simpler and cleaner way \u2013 batching the interest groups together and processing the requests in a single thread.<\/p>\n<p>And the results speak for themselves \u2013 the very same test on the very same <a href=\"http:\/\/tomcat.apache.org\/\">Tomcat<\/a> 7.0.24 with default configuration resulted in the following:<\/p>\n<ul>\n<li><strong>Average response time: 265 ms<\/strong><\/li>\n<li>Minimum response time: 6 ms<\/li>\n<li>Maximum response time: 2,058 ms<\/li>\n<li><strong>Throughput: 1,965 requests\/second<\/strong><\/li>\n<\/ul>\n<p>The specific case here is small and synthetic, but the similar improvements are achievable in the real-world applications.<\/p>\n<p>Now, before you run to rewrite all your servlets to the asynchronous servlets \u2013 hold your horses for a minute. The solution works perfectly on a subset of use cases, such as the group chat notifications and auction house price alerts. You will most likely not benefit anything for the cases where the requests are waiting behind unique database queries being completed. So as always, I must reiterate my favourite performance-related recommendation \u2013 measure everything. Do not guess anything.<\/p>\n<p>But on the occasions when the problem does fit the solution shape, I can only praise it. Besides the now-obvious improvements on throughput and latency, we have elegantly avoided possible thread starvation issues under heavy load.<\/p>\n<p>Another important aspect \u2013 the approach to asynchronous request processing is finally standardized. Independent of your favourite Servlet API 3.0 \u2013 compliant application server such as <a href=\"http:\/\/tomcat.apache.org\/download-70.cgi\">Tomcat 7<\/a>, <a href=\"http:\/\/www.jboss.org\/jbossas\/downloads\/\">JBoss 6<\/a> or <a href=\"http:\/\/www.eclipse.org\/jetty\/\">Jetty 8<\/a> you can be sure the approach works. No more wrestling with different Comet implementations or platform-dependent solutions, such as the <a href=\"http:\/\/www.oracle.com\/technetwork\/middleware\/weblogic\/overview\/index.html\">Weblogic<\/a> <em>FutureResponseServlet<\/em>.<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/plumbr.eu\/blog\/how-to-use-asynchronous-servlets-to-improve-performance\">How to use Asynchronous Servlets to improve performance<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Nikita Salnikov Tarnovski at the <a href=\"http:\/\/plumbr.eu\/blog\">Plumbr Blog<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This post is going to describe a performance optimization technique applicable to a common problem related to modern webapps. Applications nowadays are no longer just passively waiting for browsers to initiate requests, but want to start the communication themselves. A typical example could involve chat applications, auction houses, etc \u2013 the common denominator being the &hellip;<\/p>\n","protected":false},"author":328,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[165],"class_list":["post-18014","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-servlets"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to use Asynchronous Servlets to improve performance<\/title>\n<meta name=\"description\" content=\"This post is going to describe a performance optimization technique applicable to a common problem related to modern webapps. Applications nowadays are no\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to use Asynchronous Servlets to improve performance\" \/>\n<meta property=\"og:description\" content=\"This post is going to describe a performance optimization technique applicable to a common problem related to modern webapps. Applications nowadays are no\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2013-10-13T12:00:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Nikita Salnikov Tarnovski\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nikita Salnikov Tarnovski\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html\"},\"author\":{\"name\":\"Nikita Salnikov Tarnovski\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/4570b6191e21b6e609d8d00ae3b66745\"},\"headline\":\"How to use Asynchronous Servlets to improve performance\",\"datePublished\":\"2013-10-13T12:00:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html\"},\"wordCount\":955,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"keywords\":[\"Servlets\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html\",\"name\":\"How to use Asynchronous Servlets to improve performance\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2013-10-13T12:00:10+00:00\",\"description\":\"This post is going to describe a performance optimization technique applicable to a common problem related to modern webapps. Applications nowadays are no\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"java-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/10\\\/how-to-use-asynchronous-servlets-to-improve-performance.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"How to use Asynchronous Servlets to improve performance\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/4570b6191e21b6e609d8d00ae3b66745\",\"name\":\"Nikita Salnikov Tarnovski\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/da6d81f08e197d15e71a9c5fec7edde090d157ec0d00274595707d5ebc14e9c7?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/da6d81f08e197d15e71a9c5fec7edde090d157ec0d00274595707d5ebc14e9c7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/da6d81f08e197d15e71a9c5fec7edde090d157ec0d00274595707d5ebc14e9c7?s=96&d=mm&r=g\",\"caption\":\"Nikita Salnikov Tarnovski\"},\"sameAs\":[\"http:\\\/\\\/plumbr.eu\\\/blog\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/nikita-salnikov-tarnovski\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to use Asynchronous Servlets to improve performance","description":"This post is going to describe a performance optimization technique applicable to a common problem related to modern webapps. Applications nowadays are no","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html","og_locale":"en_US","og_type":"article","og_title":"How to use Asynchronous Servlets to improve performance","og_description":"This post is going to describe a performance optimization technique applicable to a common problem related to modern webapps. Applications nowadays are no","og_url":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2013-10-13T12:00:10+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","type":"image\/jpeg"}],"author":"Nikita Salnikov Tarnovski","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Nikita Salnikov Tarnovski","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html"},"author":{"name":"Nikita Salnikov Tarnovski","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/4570b6191e21b6e609d8d00ae3b66745"},"headline":"How to use Asynchronous Servlets to improve performance","datePublished":"2013-10-13T12:00:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html"},"wordCount":955,"commentCount":4,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","keywords":["Servlets"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html","url":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html","name":"How to use Asynchronous Servlets to improve performance","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2013-10-13T12:00:10+00:00","description":"This post is going to describe a performance optimization technique applicable to a common problem related to modern webapps. Applications nowadays are no","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","width":150,"height":150,"caption":"java-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2013\/10\/how-to-use-asynchronous-servlets-to-improve-performance.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"How to use Asynchronous Servlets to improve performance"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/4570b6191e21b6e609d8d00ae3b66745","name":"Nikita Salnikov Tarnovski","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/da6d81f08e197d15e71a9c5fec7edde090d157ec0d00274595707d5ebc14e9c7?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/da6d81f08e197d15e71a9c5fec7edde090d157ec0d00274595707d5ebc14e9c7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/da6d81f08e197d15e71a9c5fec7edde090d157ec0d00274595707d5ebc14e9c7?s=96&d=mm&r=g","caption":"Nikita Salnikov Tarnovski"},"sameAs":["http:\/\/plumbr.eu\/blog\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/nikita-salnikov-tarnovski"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/18014","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/328"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=18014"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/18014\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=18014"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=18014"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=18014"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}