3.4 Single-Thread Model

Java Servlet Programming, 2nd Edition > 3. The Servlet Lifecycle > 3.4 Single-Thread Model

 
< BACKCONTINUE >

3.4 Single-Thread Model

Although the normal situation is to have one servlet instance per registered servlet name, it is possible for a servlet to elect instead to have a pool of instances created for each of its names, all sharing the duty of handling requests. Such servlets indicate this desire by implementing the javax.servlet.SingleThreadModel interface. This is an empty, "tag" interface that defines no methods or variables and serves only to flag the servlet as wanting the alternate lifecycle.

A server that loads a SingleThreadModel servlet must guarantee, according to the Servlet API documentation, "that no two threads will execute concurrently in the servlet's service method." To accomplish this, each thread uses a free servlet instance from the pool, as shown in Figure 3-3. Thus, any servlet implementing SingleThreadModel can be considered thread safe and isn't required to synchronize access to its instance variables. Some servers allow the number of instances per pool to be configured, others don't. Some servers use pools with just one instance, causing behavior identical to a synchronized service( ) method.

Figure 3-3. The single-thread model

A SingleThreadModel lifecycle is pointless for a counter or other servlet application that requires central state maintenance. The lifecycle can be of some use, however, in avoiding synchronization while still performing efficient request handling.

For example, a servlet that connects to a database sometimes needs to perform several database commands atomically as part of a single transaction. Each database transaction requires a dedicated database connection object, so the servlet somehow needs to ensure no two threads try to access the same connection at the same time. This could be done using synchronization, letting the servlet manage just one request at a time. By instead implementing SingleThreadModel and having one "connection" instance variable per servlet, a servlet can easily handle concurrent requests because each instance has its own connection. The skeleton code is shown in Example 3-6.

Example 3-6. Handling Database Connections Using SingleThreadModel
import java.io.*; import java.sql.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class SingleThreadConnection extends HttpServlet                                     implements SingleThreadModel {   Connection con = null;  // database connection, one per pooled instance   public void init() throws ServletException {     // Establish the connection for this instance     try {       con = establishConnection();       con.setAutoCommit(false);     }     catch (SQLException e) {       throw new ServletException(e.getMessage());     }   }   public void doGet(HttpServletRequest req, HttpServletResponse res)                                throws ServletException, IOException {     res.setContentType("text/plain");     PrintWriter out = res.getWriter();     try {       // Use the connection uniquely assigned to this instance       Statement stmt = con.createStatement();       // Update the database any number of ways       // Commit the transaction       con.commit();     }     catch (SQLException e) {       try { con.rollback(); } catch (SQLException ignored) { }     }   }   public void destroy() {     if (con != null) {       try { con.close(); } catch (SQLException ignored) { }     }   }   private Connection establishConnection() throws SQLException {     // Not implemented.  See Chapter 9.   } }

In reality, SingleThreadModel is not the best choice for an application such as this. A far better approach would be for the servlet to use a dedicated ConnectionPool object, held as an instance or class variable, from which it could "check out" and "check in" connections. The "checked-out" connection can be held as a local variable, ensuring dedicated access. An external pool provides the servlet more control over the connection management. The pool can also verify the health of each connection, and the pool can be configured to always create some minimum number of connections but never create more than some maximum. When using SingleThreadModel, the server might create many more instances (and thus more connections) than the database can handle.

Conventional wisdom now is to avoid using SingleThreadModel. Most any servlet using SingleThreadModel could be better implemented using synchronization and/or external resource pools. It's true the interface does provide some comfort to programmers not familiar with multithreaded programming; however, while SingleThreadModel makes the servlet itself thread safe, the interface does not make the system thread safe. The interface does not prevent synchronization problems that result from servlets accessing shared resources such as static variables or objects outside the scope of the servlet. There will always be threading issues when running in a multithreaded system, with or without SingleThreadModel.


Last updated on 3/20/2003
Java Servlet Programming, 2nd Edition, © 2001 O'Reilly

< BACKCONTINUE >


Java servlet programming
Java Servlet Programming (Java Series)
ISBN: 0596000405
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net