Tuesday, October 18, 2011

SingleThreadModel : why you should not implement it and what happens if you do

According to the Servlet specifications, the SingleThreadModel interface is deprecated since the 2.4 version of the specs. The reason why it has been deprecated is that it cannot actually guarantee thread-safety, as its name suggests. But do you know what would the consequences be if you still have a servlet implement SingleThreadModel?

The side-effects of having a servlet implement SingleThreadModel are vendor-specific. Having worked with some legacy code deployed on a Tomcat 4.x container which contains a servlet that implements SingleThreadModel, I've noticed the following behavior : the container can processed a maximum of 20 simultaneous POST requests.

Explanations

Since true thread-safety cannot be achieved by implementing SingleThreadModel, each servlet container will have 2 possibilities for treating SingleThreadModel type servlets :

  • the container manages a servlet pool (2 simultaneous requests to a same servlet will actually be handled by 2 distinct instances of the requested servlet).
  • the container synchronizes the service( ) method of the requested servlet
Use-case : SingleThreadModel servlet deployed on Tomcat
 
Here's the code for the servlet we'll deployed onto any version of Tomcat for our test purpose :


public class TestServlet extends HttpServlet implements SingleThreadModel {
 private static int requestCounter = 0;
 
 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException {
  
  doGet(req, resp);
 }
 
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException {
  
  try {
   System.out.println("Start processing request with servlet " 
                        + instance : " + this + "[CPT : " + ++requestCounter + "]");
   Thread.sleep(1000000); // simulate a uber long request
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}

How to run the test?

Simply send 21 POST requests to the servlet and you'll see that the 21st request and the following ones aren't not processed by the container :



Where is this limit of 20 servlet instances configured?





Conclusion


Having a servlet implement SingleThreadModel is definitely a conception flaw that could lead to performance breakdown in the best case scenario, and to a deadlock in the worse case scenario.