Servlet与线程安全
先说结论:servlet不是线程安全的。
servlet运行过程
Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
- ①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
- ②装载并创建该Servlet的一个实例对象。
- ③调用Servlet实例对象的init()方法。
- ④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
- ⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
servlet容器如何同时处理多个请求
Servlet采用多线程来处理多个请求同时访问,Servelet容器维护了一个线程池来服务请求。线程池实际上是等待执行代码的一组线程叫做工作者线程(Worker Thread),Servlet容器使用一个调度线程来管理工作者线程(Dispatcher Thread)。
当容器收到一个访问Servlet的请求,调度者线程从线程池中选出一个工作者线程,将请求传递给该线程,然后由该线程来执行Servlet实例的service方法。当这个线程正在执行的时候,容器收到另外一个请求,调度者线程将从池中选出另外一个工作者线程来服务新的请求,容器并不关系这个请求是否访问的是同一个Servlet实例还是另外一个Servlet实例。
当容器同时收到对同一Servlet实例的多个请求,那这个Servlet实例的service方法将在多线程中并发的执行。
为什么servlet不是线程安全的
Servlet以单例多线程方式运行,也就是说当有多个请求访问同一个Servlet的方法时,只会创建一个Servlet对象。
如果Servlet方法中使用了非局部变量,就会产生线程安全问题。
方法中的局部变量全部是在栈帧的局部变量表中,栈帧是栈的一部分,而栈是线程私有的,因此Servlet中的局部变量不会引起线程安全问题。局部变量存在于栈中,如果是引用类型,那么它指向堆中的对象。
Servlet相关成员的线程安全
ServletContext:非线程安全。ServletContext是可以多线程同时读/写属性的,因此是非线程安全的。要对属性的读写进行同步处理或者进行深度Clone()。所以在Servlet上下文中尽可能少量保存会被修改(写)的数据,可以采取其他方式在多个Servlet中共享,比方我们可以使用单例模式来处理共享数据。
HttpSession:非线程安全。HttpSession对象在用户会话期间存在,只能在处理属于同一个Session的请求的线程中被访问,因此Session对象的属性访问理论上是线程安全的。但当用户打开多个同属于一个进程的浏览器窗口,在这些窗口的访问属于同一个Session,会出现多次请求,需要多个工作线程来处理请求,可能造成同时多线程读写属性。这时我们需要对属性的读写进行同步处理:使用同步块Synchronized和使用读/写器来解决。
ServletRequest:线程安全。对于每一个请求,由一个工作线程来执行,都会创建有一个新的ServletRequest对象,所以ServletRequest对象只能在一个线程中被访问,因此ServletRequest是线程安全的。注意:ServletRequest对象在service方法的范围内是有效的,不要试图在service方法结束后仍然保存请求对象的引用。
如何安全地使用Servlet
尽量使用局部变量。多线程并不共享局部变量,所以我们要尽可能的在servlet中使用局部变量。
对需要异步调用的代码块加锁,不过这意味着线程需要排队处理,因为在使用同板块的时候要尽可能的缩小同步代码的范围,不要直接在sevice方法和响应方法上使用同步,这样会严重影响性能。
使用线程安全的类:如使用Vector代替ArrayList,使用Hashtable代替HashMap。
不要在Servlet中创建自己的线程来完成某个功能。Servlet本身就是多线程的,在Servlet中再创建线程,将导致执行情况复杂化,出现多线程安全问题。
在多个servlet中对外部对象(比方文件)进行修改操作一定要加锁,做到互斥的访问。
#########
Servlet与线程安全的更多相关文章
- Servlet 是否线程安全 看完便知
Servlet 是否线程安全 看完便知 转自:http://blog.sina.com.cn/s/blog_6448959f0100kct7.html 摘 要:介绍了Servlet多线程机制, ...
- 玩转Web之servlet(五)---- 怎样解决servlet的线程安全问题
servlet默认是存在线程安全问题的,但是说白了,servlet的线程安全问题实际上就是多线程的线程安全问题,因为servlet恰巧是一个多线程才会出现安全性问题. 浏览器每次通过http协议去提交 ...
- Servlet的线程安全
Servlet的线程安全 一.什么是Servlet的线程安全 1.在Servlet的整个生命周期中,构造方法只被执行一次.也就是说,在Servlet的整个生命周期中,只存在一个Servlet实例对象. ...
- servlet是线程安全的么
servlet生命周期 三个重要方法 1 init() 进行资源的加载 2 service() 处理请求,根据请求方式,调用doGet或者doPost 3 destroy() 进行资源的释放 ser ...
- 漫画 | Servlet属于线程安全的吗?
Servlet属于线程安全的吗? Servlet不是线程安全的 在JSP中,只有一行代码:<%=A+B %>,运行结果如何? jsp和servlet有什么关系? jsp一般被用在view层 ...
- servlet开发(二)之servlet的线程安全问题
之所以考虑线程安全问题,是因为引入了多线程.多线程指的是这个程序(一个进程)运行时产生了不止一个线程.如果不考虑多线程的话,程序执行只有一条路径,就像人在敲代码的时候只能敲代码,不能戴上耳机听歌.引入 ...
- servlet与线程与jdbc connection的关系
servlet与线程与jdbc connection的关系 都是一一绑定的关系, servlet接受那么多此请求. 一个请求,对应一个线程,对应一个DB POOL的connection. 因为conn ...
- Java面试题:Servlet是线程安全的吗?
Servlet不是线程安全的. 要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP请求时 ...
- servlet 最大线程数探索笔记
servlet默认是单例模式的,所以是单例多线程的.如果实现了singleservlet是可以多个servlet实例,下面是一个servlet的请求生命周期 1 客户端请求该 Servlet:加载 S ...
- Servlet的线程是不是共享同一个requset对象及servlet多线程
servlet多线程 一,servlet容器如何同时处理多个请求. Servlet采用多线程来处理多个请求同时访问,Servelet容器维护了一个线程池来服务请求.线程池实际上是等待执行代码的一组 ...
随机推荐
- Python 装饰器的诞生过程
Python中的装饰器是通过利用了函数特性的闭包实现的,所以在讲装饰器之前,我们需要先了解函数特性,以及闭包是怎么利用了函数特性的 ① 函数特性 Python中的函数特性总的来说有以下四点: 1. ...
- Nginx+tomcat配置负载均衡集群
操作系统版本:Centos 6.4 Nginx版本:nginx-1.3.15.tar.gz wget http://nginx.org/download/nginx-1.5.9.tar.gz JDK版 ...
- DOM简介
什么是DOM? DOM 是 Document Object Model(文档对象模型)的缩写. W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容. ...
- RAW nand clear NAND eMMC
raw NAND: raw NAND即是一般的NAND Flash内存芯片,所有的ECC除错机制(Error Correcting Code).区块管理(Block Management).磨损均衡技 ...
- [转]Algolia的分布式搜索网络架构
转自:http://www.csdn.net/article/2015-03-11/2824176-the-architecture-of-algolias-distributed-search-ne ...
- [转]运动检测(前景检测)之(二)混合高斯模型GMM
转自:http://blog.csdn.net/zouxy09/article/details/9622401 因为监控发展的需求,目前前景检测的研究还是很多的,也出现了很多新的方法和思路.个人了解的 ...
- hdp (ambari) 集成hue
ambari-server resetambari-admin-password-reset https://github.com/EsharEditor/ambari-hue-service可以基于 ...
- SpringBoot入门学习(二)
第一讲我们已经讲解了入门Demo,这一讲我们主要讲解包含以下内容 项目内一些属性配置 自定义属性配置 ConfigurationProperties配置 (1)第一个工程创建的时候会自动在工程下创建a ...
- 获取浏览器版本型号(C#)
private string GetClientBrowserVersions() { string browserVersions = string.Empty; HttpBrowserCapabi ...
- web.xml<context-param>与<init-param>的作用与区别
<context-param>的作用:web.xml的配置中<context-param>配置作用1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件we ...