Servlet单例非安全解析
Servlet容器默认是采用单实例多线程的方式处理多个请求
Servlet容器<Web容器<应用服务器?apache<tomcat<websphere
Servlet不是线程安全的。
线程安全,指的是在多线程环境下,一个类在执行某个方法时,对类的内部实例变量的访问安全与否。
要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的。
当Tomcat接收到Client的HTTP请求时,Tomcat从线程池中取出一个线程,之后找到该请求对应的Servlet对象并进行初始化,之后调用service()方法。
要注意的是每一个Servlet对象再Tomcat容器中只有一个实例对象,即是单例模式。如果多个HTTP请求请求的是同一个Servlet,那么着两个HTTP请求对应的线程将并发调用Servlet的service()方法。
设计线程安全的程序:
1、实现 SingleThreadModel 接口(不推荐使用)
public class ThreadSafeServlet extends HttpServlet implements SingleThreadModel
2、同步对共享数据的操作
使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中的Servlet可以通过同步块操作来保证线程的安全。(处理客户请求的吞吐量降低,而且很多客户处于阻塞状态)
1
2
3
4
5
6
7
|
Synchronized ( this ){ //同步代码块使用代替注解在方法上。 Output = response.getWriter (); Try { Thread. Sleep ( 5000 ); } Catch (Interrupted Exception e){} output.println( "用户名:" +Username+ "<BR>" ); } |
3、只要在Servlet里面的任何方法里面都不使用全局静态变量和实例变量,那么该Servlet就是线程安全的。(使用局部变量);
public static String name = "Hello"; //静态变量,可能发生线程安全问题
int i; //实例变量,可能发生线程安全问题
1
2
|
String user = "" ; user = request.getParameter( "user" ); |
PS:
Servlet并非只是单例的. 当container开始启动,或是客户端发出请求服务时,Container会按照容器的配置负责加载和实例化一个Servlet(也可以配置为多个,不过一般不这么干).不过一般来说一个servlet只会有一个实例。
1) Struts2的Action是原型,非单实例的;会对每一个请求,产生一个Action的实例来处理。
2) Struts1的Action,Spring的Ioc容器管理的bean 默认是单实例的.
Struts1 Action是单实例的,spring mvc的controller也是如此。因此开发时要求必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
Spring的Ioc容器管理的bean 默认是单实例的。
Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)。
当Spring管理Struts2的Action时,bean默认是单实例的,可以通过配置参数将其设置为原型。(scope="prototype )
最新文章
- js开发笔记
- POJ 2774 Long Long Message 后缀数组
- [nRF51822] 4、 图解nRF51 SDK中的Schedule handling library 和Timer library
- Zygote浅谈
- 使用webbench对不同的web服务器进行压力测试
- 使用命令参数方式指定log4j配置文件
- Play framework logging设置
- 已有a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列
- VJP1456 最小总代价(状压)
- 使用GDB生成coredump文件【转载】
- IOS开发中长按的手势事件编程
- Android源码博文集锦1
- 使用T-SQL语句操作视图
- vijos:旅行家的预算[贪心]
- spring中获取applicationContext(2)
- 动态切换tableView中的cell的种类
- [洛谷P4512]【模板】多项式除法
- C/C++中0xcccccccc...
- 内存分配malloc函数注意事项。
- redis string类型
热门文章
- HDU 3062 简单的2-SAT问题
- bzoj 3772 精神污染 主席树+dfs序
- [转]Fedora22添加国内软件源和本地软件源
- springmvc和dubbo整合时,不配置spring listener报错找不到/WEB-INF/config/applicationContext.xml
- BMP格式,转载
- CSS制作简单图标
- pycharm查看代码注释的方法,代码编写日志及作者信息等
- Java SpringMVC实现PC端网页微信扫码支付完整版
- CentOS 5 全功能服务器搭建
- leetCode 78.Subsets (子集) 解题思路和方法