线程模型
缺省情况,servlet引擎只载人一个servlet的单一实例,servlet予以服务的多个请求运行于单
线程下,但却共享同样的实例以及同样的实例变量。这说明了几点,最值得注意的是实例变量
不是线程安全的。例如,对于以下servlet:
package jspcr.servlets;
import java.io.*;
import java.sql.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ColiderServlet extends HttpServlet
{
private Connection con;
public void doGet(HttpServletRequest request,HttpServletResponse response) throw ServletException,IOException
{
try
{
Class.forName("sun.jdbc.odbc...");
con=DriverManager.getConnection("jdbc:odbc");
}
catch (Exception e)
{
throw new ServletException(e.getMessage());
}
}
}
考虑两个请求到达同一线程,只间隔几百毫秒,这时会发生什么’第一个请求打开数据库
连接,保存其引用至con实例变量,然后它使用连接执行一个表格修改或其他数据库操作。同时,
第二个请求到达,打开另一连接,在同一个con实例变量中保存其引用:如果第一个操作完成,
试图做另一个数据库操作,其不再拥有初始连接对象——它只知道第2个c然后当其试图使用第2
个连接时就会发生错误c
实例变量同样类型的问题可能发生在调用其服务方法中其他方法的servl欧中。如果这些方法
试图访问服务方法中创建的已被保存在一个实例变量中的servlet请求、响应或任意对象,没有任
何方式可以确保另一线程内的请求由于将其自身对象的引用保存到变量中啊不打断该变量的连
续性“c
最安全的方式是不仅使用实例变量,还耍在服务方法中定义的局部变量;
单线程模型
虽然单实例多线程模型为缺省模型,一—个servlet也可以通过实现singIeThreadModel改变此
行为。此接口不包含方法,通知servlet引擎应该创建一个实例池,并分配每个进入请求到其自己
的实例和线程。这将确保两个被同一实例处理的请求不会在其服务方法执行中被f7断。实例变
量一次只能被一个请求所影响。进而实现线程安全c注意,因为可能存在多实例,所以没有什
么力式可以阻止它们在不同的线程中并发执行:如果它们访问像文件或数据库这样的外部资源,
仍会产生矛盾。在singIeThreadModel中有儿种方式可以解决用其他方式不能很好解决的问题。