By default, servlets are not thread-safe. The methods in a single servlet instance are usually executed numerous times simultaneously (up to the available memory limit). Each execution occurs in a different thread, though only one servlet copy exists in the servlet engine.
This is efficient system resource usage, but is dangerous because of the way Java manages memory. Because variables belonging to the servlet class are passed by reference, different threads can overwrite the same memory space as a side effect. To make a servlet (or a block within a servlet) thread-safe, do one of the following:
Synchronize write access to all instance variables, as in public synchronized void method() (whole method) or synchronized(this) {...} (block only). Because synchronizing slows response time considerably, synchronize only blocks, or make sure that the blocks in the servlet do not need synchronization.
For example, this servlet has a thread-safe block in doGet() and a thread-safe method called mySafeMethod():
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class myServlet extends HttpServlet { public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //pre-processing synchronized (this) { //code in this block is thread-safe } //other processing; } public synchronized int mySafeMethod (HttpServletRequest request) { //everything that happens in this method is thread-safe } } |
Use the SingleThreadModel class to create a single-threaded servlet. When a single-threaded servlet is deployed to the Sun Java System Web Server, the servlet engine creates a servlet instance pool used for incoming requests (multiple copies of the same servlet in memory). You can change the number of servlet instances in the pool by setting the singleThreadedServletPoolSize property in the Sun Java System Web Server-specific web application deployment descriptor. For more information, see Chapter 7, Deploying Web Applications. Servlet is slower under load because new requests must wait for a free instance in order to proceed. In load-balanced applications, the load automatically shifts to a less busy process.
For example, this servlet is completely single-threaded:
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class myServlet extends HttpServlet implements SingleThreadModel { servlet methods... } |
If a servlet is specifically written as a single thread, the servlet engine creates a pool of servlet instances to be used for incoming requests. If a request arrives when all instances are busy, it is queued until an instance becomes available. The number of pool instances is configurable in the sun-web.xml file, in the singleThreadedServletPoolSize property of the sun-web-app element.