代码编织梦想

概要

Servlet 默认是单例模式,在web 容器中只创建一个实例,所以多个线程同时访问servlet的时候,Servlet是线程不安全的。
那么 web 容器能为每个请求创建一个Servlet的实例吗?当然是可以的,只要Servlet实现SingleThreadModel接口,就可以了。

SingleThreadModel

该接口为每次请求创建一个servlet实例。此接口没有方法,跟Serializable接口一样只是一个标识接口。

注意,singlethreadmodel并不能解决所有的线程安全问题。例如,会话属性和静态变量仍然可以同时通过多线程的多个请求访问,即使用实现SingleThreadModel 接口的 servlet。建议开发人员采取其他方法来解决这些问题,而不是实现此接口,
例如避免使用实例变量或同步访问这些资源的代码块。
SingleThreadModel这个接口 Servlet API 2.4版本过时,不推荐大家使用了因为它存在性能问题,下面会介绍。

SingleThreadModel 使用示例

import javax.servlet.SingleThreadModel 
public class MyServlet extends HttpServlet implements SingleThreadModel {

只要Servlet实现 SingleThreadModel 接口就可以了。

Servlet 对象创建 源码分析

org.apache.catalina.core.StandardWrapper类是对应一个Servlet的容器,下面我们分析StandardWrapper是怎么创建Servlet实例的。

allocate() 创建Servlet 实例

首先判断当前servlet是不是 SingleThreadModel,如果不是,则使用双重检查的方式创建 instance 单例实例。 通过调用loadServlet方法进行创建 instance。

  • 只要Servlet不是SingleThreadModel,则创建Servlet的单例实例

如果第一次访问Servlet,则singleThreadModel属性默认是false,需要调用loadServlet方法加载Servlet后才能判断该Servlet是不是SingleThreadModel模式。


1. 如果是SingleThreadModel模式并且是新创建的实例,则把当前instance添加到instancePool中,并nInstances++。
2. 如果不是SingleThreadModel模式,则更新countAllocated+1,并且返回Servlet的instance实例


只有SingleThreadMode才能到synchronized块,因为,不是SingleThreadMode的已经执行return方法了。
判断当前Servlet创建的实例数量是否超过了maxInstances数量,默认maxInstances=20
如果超过当前则wait等待,否则,调用loadServlet()创建Servlet实例并添加到instancePool中。并更新nInstances数量。
* 从这里可以看出每次都会调用loadServlet()方法来创建Servlet实例对象的。

SingleThreadMode 性能问题

从这里看出如果使用SingleThreadMode 模式,有两处性能问题
1. 每个Servlet 创建多个对象实例
2. 如果并发高,每个servlet同时只能支持20线程的并发访问。挂起超过20个的线程。

loadServlet() 方法


1. 创建Servlet实例对象
2. 判断该Servlet 是不是 SingleThreadMode
3. 初始化Servlet

本人简书blog地址:http://www.jianshu.com/u/1f0067e24ff8    
点击这里快速进入简书

GIT地址:http://git.oschina.net/brucekankan/
点击这里快速进入GIT

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jijianshuai/article/details/77878713

tomcat 怎么停止服务的?_汲建帅的博客-爱代码爱编程_tomcat怎么停止

通过分析 Tomcat catalina.bat 原理解析时,发现启动tomcat和关闭tomcat都是调用 MAINCLASS 启动类进行操作的。 这里有个疑问,既然都是通过调用 MAINCLASS 类进行操作的,那

tomcat filter 源码分析_汲建帅的博客-爱代码爱编程_tomcat源码filter

Filter 概述 Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。 通过Filter技术,开发人员可以实现用户在访问

tomcat filter 自己动手实现_汲建帅的博客-爱代码爱编程_tomcat 自定义过滤器

Filter 简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文

tomcat webappclassloader 类加载机制源码分析_汲建帅的博客-爱代码爱编程

需要了解的知识JVM 类加载机制深入浅出 tomcat中的ClassLoader 启动类加载器(BootStrap ClassLoader):引导类装入器是用本地代码实现的类装入器,它负责将 jdk中jre/lib下

美团Java研发岗二面:什么叫线程安全?servlet是线程安全吗?-爱代码爱编程

前言: 再过一个月的时间就是金三银四了,相信不少的朋友对于已经做好了充足的准备来应对这一次春招,小编对大家也没有太多的建议和帮助,分享一些你们面试上面可以用得到的一些面试题。今天主要给大家分享多线程(线程安全)方面的面试题,看到文章的小伙伴一定要看到后面哦,有海量的面试题分享给大家哟。 1、什么叫线程安全?servlet是线程安全吗? 线程安全 就是

为什么servlet线程不安全性?原因如下:-爱代码爱编程

我们在写java后端时,要知道servlet是线程不安全的,这是单列模式导致的。 单例模式概要: 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。 当不同的请求都调用这一个servlet,单例模式只new ()一次,只在堆里申请了一个对象空间,即只实例化了一次。所以,不管来了多少请求,都是这

什么叫线程安全?servlet是线程安全吗?-爱代码爱编程

1、什么叫线程安全?servlet是线程安全吗? 线程安全 就是多线程在运行期间不会产生不符合常规的数据。 同样在多线程访问同一代码,不会产生不确定的结果 线程安全首先呢他的是多线程,至少是2个。因为一个线程那肯定是线程安全的。就你自己一个线程执行没有人给你争用资源。你是在串行执行,不会出现不确定结果。 如果有多个线程 那问题可就多了

Servlet 有关线程安全的问题及解决方式-爱代码爱编程

Servlet的线程安全 由于 Servlet 采用的是单例模式,也就是整个应用中只有一个实例对象。所以我们需要分析这个唯一的实例对象中的类成员是否线程安全 模拟用户登录功能来查看 Servlet 线程是否安全 结论:一个浏览器代表一个线程,多个浏览器代表多个线程。按理说我们期望的应该是每个浏览器查看的都应该是自己的用户名。而现在的结果是浏览器中数

servlet线程安全吗?-爱代码爱编程

目录 servlet线程安全吗?servlet执行流程web 容器能为每个请求创建一个Servlet的实例吗?SingleThreadModelspringmvc是线程安全的吗?springmvc singleton有几种解决方法总结 servlet线程安全吗? servlet默认是单例模式,在web容器中只创建一个实例,所以多个线程同时访问

你能证明Servlet线程不安全吗?-爱代码爱编程

Servlet默认是线程不安全的! Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。   当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。 当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实