2

What exactly is the advantage of asynchronous Servlets? I had assumed that it meant that a web-app container listener thread would be 'freed up' to handle another client request whilst a potentially long-running task is executed by the Servlet. Experiments with Tomcat and Spring 3.2 don't support this. Is the benefit some sort of memory-management improvement instead?

I have Tomcat set up to listen on a single thread. My @Controller calls a downstream @Service that calls Thread.sleep(10000). I issue two requests a second apart, and it takes 10 seconds for the first to get a response, and then a further 10 seconds to get the second response (so 20 seconds all in all). I would expect to get both responses back in 11 seconds if my understanding of asynchronous Servlets was correct.

Spring config:

<mvc:annotation-driven>
    <mvc:async-support task-executor="taskExecutor" default-timeout="20000" />
</mvc:annotation-driven>
<context:component-scan base-package="com.company" />

<task:executor id="taskExecutor" pool-size="5-20" queue-capacity="100"/>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/spring-config/app-context.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath:/spring-config/web-context.xml
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

Controller

@Controller
public class AsyncController {
    @Autowired
    private BlockingService service;

    @RequestMapping("/test")
    public @ResponseBody Callable<String> test()
    {
        return new Callable<String>() {
            public String call() throws Exception {
                return service.block(System.currentTimeMillis());
            }
        };
    }
}

Service

@Service
public class BlockingService {
    public String block(long timeBefore)
    {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Before: "+timeBefore+"\nTime: "+System.currentTimeMillis();
    }
}
DeejUK
  • 12,891
  • 19
  • 89
  • 169
  • *"What exactly is the advantage of asynchronous Servlets?"* being able to use a servlet for websockets or SSE. I don't do Spring, but it look like you mixed up the concepts of a web front controller and business controller/service. Whatever you need is very easy with the standard Java EE stack by the way. – BalusC Jul 05 '13 at 11:08
  • Thanks for your comment. How do asynchronous servlets enable websockets? I thought SSE were possible with synchronous servlets; in which case what advantage does the asynchonicity offer? – DeejUK Jul 05 '13 at 11:18
  • Writing data to it from inside a different thread/request, obviously. – BalusC Jul 05 '13 at 11:28
  • Could you post the whole demo project somewhere, like on github or gist? – Petr Jul 05 '13 at 11:43

1 Answers1

2

Have a look at this answer. Make sure the maxConnections is set when using a BIO connector, otherwise it defaults to maxThreads

Also bear in mind that if you are using tabbed browsing it will queue the requests client side if the urls are the same. You can add querystring parameters to test this.

It is best to test using two types of browser.

Community
  • 1
  • 1