Servlets


Q: Are servlets multi-threaded?
A: Yes, servlets are normally multi-threaded. The servlet container allocates a thread for each new request for a single servlet without any special programming. Each request thread for your servlet runs as if a single user were accessing it alone, but you can use static variables to store and present information that is common to all threads, like a hit counter for instance.
Q: What is a service thread and how do I create one?
A: The most common use of service threads are those used by a servlet container to handle the HTTP request-response process with a Java servlet. Servlet containers use an independent thread of execution so they can process many concurrent requests to many servlets and manage the overall performance of the server. Servlet requests are handled through the service() method, so they are named service threads, but other Java applications may use a similar service scheme. Servlet containers automatically create or obtain service threads from a thread pool when a new HTTP request is received, so they do not need to be created explicitly in your servlet code.
Q: How does the container handle concurrent requests?
A: Servlet containers usually manage concurrent requests by creating a new Java thread for each request. The new thread is given an object reference to the requested servlet, which issues the response through the same thread. This is why it is important to design for concurrency when you write a servlet, because multiple requests may be handled by the same servlet instance.
Q: Are you saying there is only one servlet instance for all requests?
A: The way that servlet containers handle servlet requests is not prescribed to this extent; they may use a single servlet, they may use servlet pooling, it depends on the vendor's system architecture. New threads are not necessarily created for every servlet request but may be recycled through a worker thread pool for efficiency. The point is that you should write your servlet code to take account of a multi-threaded context regardless of the container implementation you happen to be using. In other words, you should adhere to the principle of write once, run anywhere.
Q: Are servlet requests handled first come, first served?
A: The use of a single servlet to handle multiple requests is usually done with Java threads. For each HTTP request the servlet container assigns a worker thread in which to execute the servlet code and a reference to the relevant servlet instance to call its service methods. The priority order by which the service threads are acquired and process the request depends on the detailed implementation of the servlet container. The natural principle is that it should be first come first served, but the actual execution sequence also depends on the thread scheduling scheme in the Java virtual machine. Servlet containers normally limit the number of service threads that can be run concurrently, so pending requests are typically added to a queue. Once a service thread is assigned to a request, the sequence in which the thread is executed depends on the thread scheduling system of the Java Runtime Environment (JRE). Threads can enter complex stop, start sequences in contention with other service threads, which is why your servlet code needs to be thread safe.

The single thread model

Q: What is the single threaded model?
A: Standard servlets are normally handled in a multi-threaded context in the servlet container. A number of virtually simultaneous requests for a single servlet could be handled by different threads using the same servlet instance. Any number of threads could access or modify the static and instance fields of a single servlet instance in an unpredictable sequence. This makes the instance fields of servlets as vulnerable to threading issues as static fields, and modification of shared resources must be considered carefully. If your servlet implements the SingleThreadModel interface, it gets a guarantee from the servlet container that any single instance of the servlet will only be accessed by one thread at a time. The container either synchronizes access to the servlet's service() method, or uses a single instance of the servlet drawn from a pool. The single threaded model adds a performance overhead to locking or managing servlet instances, so should not be used lightly. Generally, it is best to ensure synchronized access to servlet resources in your application code.
Q: Why use SingleThreadedModel if servlets are multi-threaded?
A: The SingleThreadedModel interface is used to ensure the safety of servlets that are vulnerable to thread safety issues. Normally, servlets should be written to run safely in a multi-threaded environment, and are executed in this context. The SingleThreadedModel is a way to override the normal multi-threaded execution context of the servlet container.
Q: How do I implement the single threaded model?
A: To create a servlet that a container will manage on a single threaded basis it must declare that it implements the javax.servlet.SingleThreadModel interface. This is a marker interface, there are no extra methods to fulfil, but this is sufficient for the container to identify the type and manage it accordingly.
public class SingleThreadServlet extends HttpServlet
                              implements SingleThreadModel {

 // Standard HTTP servlet methods
}
      
The servlet container will typically synchronize access to a single instance of the servlet, or create a pool of servlet instances and allocate one request per instance.
Q: Should I use the SingleThreadedModel?
A: Not unless you have very good reason. The SingleThreadedModel interface has been deprecated, which means that it should not be used and may be removed in a later release of the Java servlet specification and Application Programming Interface (API). It has never really been advisable to implement the SingleThreadedModel, you should always aim to address thread safety issues in servlets using standard Java programming techniques.
Q: How can I invoke servlet pooling with SingleThreadedModel?
A: The SingleThreadedModel servlet specification does not require the creation of a pool of servlets. A single threaded model implementation may also synchronize access to a single servlet instance to achieve the same outcome, so that only one request is processed at a time. Apache Tomcat uses the synchronized approach, other servlet containers may use the pooled approach. If you are concerned about the performance impact of synchronized access to the servlet instance, it would be preferable to re-design your servlet so that it does not depend on this mechanism at all. For example, you might create a synchronized block around the statements that are vulnerable to threading issues. By doing away with the single threaded model, you will minimise the performance impact of thread control.

Servlet thread management

Q: Can my servlet control the number of threads it accepts?
A: Your servlet should be designed to be thread safe and not to anticipate any limit to the number of concurrent requests it will receive. You should configure the number of concurrent requests to accept in your servlet container configuration. In Apache Tomcat this property is set in the server.xml file's Connector element, as below.
<Connector
  className="org.apache.catalina.connector.http.HttpConnector"
  minProcessors="3"
  maxProcessors="20"
  acceptCount="10"/>
    
  • The acceptCount attribute sets the number of requests that can be queued waiting to be handled.
  • The minProcessors attribute sets the number of request processors that are created when the servlet container starts up.
  • The maxProcessors attribute sets the total number of request processors or that can be used to handle requests.