一篇经典的Single-Thread Model原著(节选)

Servlet的SingleThreadModel接口用于确保每个请求由池中独立的实例处理,从而避免线程并发执行。虽然该接口可以简化数据库连接等资源的同步问题,但现代实践中通常建议使用同步和外部资源池来代替,因为SingleThreadModel可能会导致过多的实例创建,增加数据库负载,并不总是提供完全的线程安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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,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.

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.

Example 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.  
  }
}

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.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值