前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Servlet 是线程安全的吗?

Servlet 是线程安全的吗?

作者头像
java404
发布2018-05-18 12:28:29
2.7K0
发布2018-05-18 12:28:29
举报
文章被收录于专栏:java 成神之路java 成神之路

概要

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

SingleThreadModel

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

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

SingleThreadModel 使用示例

代码语言:javascript
复制
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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.09.03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概要
  • SingleThreadModel
  • SingleThreadModel 使用示例
  • Servlet 对象创建 源码分析
    • allocate() 创建Servlet 实例
    • SingleThreadMode 性能问题
    • loadServlet() 方法
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档