Servlet 是线程安全的吗?

Servlet 是线程安全的吗?

置顶 2017年09月07日 11:00:14 阅读数:4977 标签: servlet线程安全tomcat源码分析 更多

个人分类: tomcat

版权声明:本文为博主原创文章,转载请说明来源。 https://blog.csdn.net/jijianshuai/article/details/77878713

概要

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 {
  • 1
  • 2

只要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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值