Servlet到底是单例还是多例你了解吗?

简介: 为一个Java Web开发者,你一定了解和学习过Servlet。或许还曾在面试中被问到过Servelt是单例还是多例这个问题。 遇到这个问题,你是否曾深入了解过,还是百度或者Google了一下,得到答案就OK了呢? 我们今天从Servlet规范及Tomcat源码实现的角度,分析下这个问题。

为一个Java Web开发者,你一定了解和学习过Servlet。或许还曾在面试中被问到过Servelt是单例还是多例这个问题。

遇到这个问题,你是否曾深入了解过,还是百度或者Google了一下,得到答案就OK了呢?

我们今天从Servlet规范及Tomcat源码实现的角度,分析下这个问题。

在Servlet规范中,对于Servlet单例与多例定义如下:

“Deployment Descriptor”, controls how the servlet container provides instances of the servlet.For a servlet not hosted in a distributed environment (the default), the servlet container must use only one instance per servlet declaration. However, for a servlet implementing the SingleThreadModel interface, the servlet container may instantiate multiple instances to handle a heavy request load and serialize requests to a particular instance.

上面规范提到,
如果一个Servlet没有被部署在分布式的环境中,一般web.xml中声明的一个Servlet只对应一个实例。

而如果一个Servlet实现了SingleThreadModel接口,就会被初始化多个实例。实例有多少呢,这里没细说。

下面再从Tomcat的源码中找寻下具体的参考实现是什么样子的。以下代码来源于Tomcat的StandardWrapper类。我把其中不太相关的部分做了删除。

public Servlet allocate() throws ServletException {
boolean newInstance = false;
if (!singleThreadModel) { // Load and initialize our instance if necessary if (instance == null) { synchronized (this) { if (instance == null) { try { instance = loadServlet(); } catch (ServletException e) {}}}} if (singleThreadModel) { if (newInstance) { synchronized (instancePool) { instancePool.push(instance); //如果实现STM接口,就放到一个栈里 nInstances++; }} } else { if (!newInstance) { countAllocated.incrementAndGet(); } return (instance); } } synchronized (instancePool) { while (countAllocated.get() >= nInstances) { // Allocate a new instance if possible, or else wait if (nInstances < maxInstances) { try { instancePool.push(loadServlet()); nInstances++; } catch (ServletException e) {} } else { try { instancePool.wait(); } catch (InterruptedException e) { // Ignore }} } countAllocated.incrementAndGet(); return instancePool.pop(); }}
/**
* Load and initialize an instance of this servlet, if there is not already
* at least one initialized instance. This can be used, for example, to
* load servlets that are marked in the deployment descriptor to be loaded
* at server startup time.
*/ public synchronized Servlet loadServlet() throws ServletException { // Nothing to do if we already have an instance or an instance pool if (!singleThreadModel && (instance != null)) return instance; //注意此处,如果存在实例就直接返回 Servlet servlet; try { InstanceManager instanceManager = ((StandardContext)getParent()).getInstanceManager(); try { servlet = (Servlet) instanceManager.newInstance(servletClass); } catch (ClassCastException e) { } if (servlet instanceof SingleThreadModel) { if (instancePool == null) { instancePool = new Stack<>(); } //此处,使用Stack存放STM的Servlet singleThreadModel = true; } initServlet(servlet); } finally { } return servlet; }

那一个实现了SingleThreadModel接口的Servlet,一般会初始化多少个实例呢?
StandardWrapper类中有两个属性,其中maxInstance初始为20。所以上面的问题就有了答案。

/**
 * Does this servlet implement the SingleThreadModel interface?
 */
protected volatile boolean singleThreadModel = false; /** * Maximum number of STM instances. */ protected int maxInstances = 20;

由于SingleThreadModel已经声明为废弃,官方不建议使用。我们这里只是让大家了解下。

总结下,一个Servlet究竟有几个实例呢?受如下几个原因影响:
是否在分布式环境中部署
是否实现SingleThreadModel,如果实现则最多会创建20个实例
在web.xml中声明了几次,即使同一个Servlet,如果声明多次,也会生成多个实例。



作者:侯树成
链接:http://www.jianshu.com/p/caba33d8f3fd
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关文章
|
11月前
|
应用服务中间件
秋招面试:如何证明Servlet是单例的?
秋招面试:如何证明Servlet是单例的?
|
17天前
|
Java
学校教师管理系统【JSP+Servlet+JavaBean】(Java课设)
学校教师管理系统【JSP+Servlet+JavaBean】(Java课设)
19 1
|
17天前
|
Java
人事管理系统【JSP+Servlet+JavaBean】(Java课设)
人事管理系统【JSP+Servlet+JavaBean】(Java课设)
16 0
|
29天前
使用Servlet上传多张图片——前台页面层(Index.jsp)
使用Servlet上传多张图片——前台页面层(Index.jsp)
12 0
|
4月前
|
设计模式 前端开发 Java
了解 Spring MVC 架构、Dispatcher Servlet 和 JSP 文件的关键作用
Spring MVC 是 Spring 框架的一部分,是一个 Web 应用程序框架。它旨在使用 Model-View-Controller(MVC) 设计模式轻松构建Web应用程序。
63 0
|
3月前
|
存储 前端开发 Java
JavaWeb:servlet+jsp+mybatis商品管理增删改查
商品管理通常包括增加(添加)、删除、修改和查询商品信息
43 1
JavaWeb:servlet+jsp+mybatis商品管理增删改查
|
3月前
|
设计模式 前端开发 Java
基于JSP/SERVLET学生管理系统
基于JSP/SERVLET学生管理系统
|
3月前
|
Java 数据安全/隐私保护 计算机视觉
基于JSP/SERVLET实现的人脸识别考勤系统(二)
基于JSP/SERVLET实现的人脸识别考勤系统
|
3月前
|
Java 关系型数据库 数据库
基于JSP/SERVLET实现的人脸识别考勤系统(一)
基于JSP/SERVLET实现的人脸识别考勤系统
|
3月前
|
安全 Java
javaweb实训第四天下午——员工管理系统-JSP&Servlet&JDBC综合练习-CRUD
1.课程介绍 Servlet细节; (掌握) 员工信息相关的CRUD; (掌握) 部门信息相关的CRUD; (掌握) 2.Servlet细节 2.1.多种匹配方式
38 0