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 )

 

Servlet单例非安全解析的更多相关文章

  1. Servlet 单例多线程【转】

    源地址:Servlet 单例多线程 Servlet如何处理多个请求访问?Servlet容器默认是采用单实例多线程的方式处理多个请求的:1.当web服务器启动的时候(或客户端发送请求到服务器时),Ser ...

  2. Servlet 单例多线程详解(六)

    一.Servlet 单例多线程 Servlet如何处理多个请求访问?Servlet容器默认是采用单实例多线程的方式处理多个请求的:1.当web服务器启动的时候(或客户端发送请求到服务器时),Servl ...

  3. Servlet 单例多线程

    Servlet如何处理多个请求访问? Servlet容器默认是采用单实例多线程的方式处理多个请求的: 1.当web服务器启动的时候(或客户端发送请求到服务器时),Servlet就被加载并实例化(只存在 ...

  4. servlet单例多线程

    Servlet如何处理多个请求访问? Servlet容器默认是采用单实例多线程的方式处理多个请求的: 1.当web服务器启动的时候(或客户端发送请求到服务器时),Servlet就被加载并实例化(只存在 ...

  5. [转]Servlet 单例多线程

    Servlet如何处理多个请求访问? Servlet容器默认是采用单实例多线程的方式处理多个请求的: 1.当web服务器启动的时候(或客户端发送请求到服务器时),Servlet就被加载并实例化(只存在 ...

  6. Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean

    Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean 七千字长文深刻解读,Spirng中是如何初始化单例bean的,和面试中最常问的Sprin ...

  7. Servlet到底是单例还是多例你了解吗?

    为一个Java Web开发者,你一定了解和学习过Servlet.或许还曾在面试中被问到过Servelt是单例还是多例这个问题. 遇到这个问题,你是否曾深入了解过,还是百度或者Google了一下,得到答 ...

  8. Spring 的Controller 是单例or多例

    Spring 的Controller 是单例or多例 你什么也不肯放弃,又得到了什么? 背景:今天写代码遇到一个Controller 中的线程安全问题,那么Spring 的Controller 是单例 ...

  9. 【Spring源码分析】非懒加载的单例Bean初始化过程(下篇)

    doCreateBean方法 上文[Spring源码分析]非懒加载的单例Bean初始化过程(上篇),分析了单例的Bean初始化流程,并跟踪代码进入了主流程,看到了Bean是如何被实例化出来的.先贴一下 ...

随机推荐

  1. 76. Spring Boot完美解决(406)Could not find acceptable representation原因及解决方法

    [原创文章]        使用Spring Boot的Web项目,处理/login请求的控制器方法(该方法会返回JSON格式的数据).此时如果访问localhost:8080/login.html, ...

  2. struts2常用类型的Result

    2.2.1. dispatcher dispatcher类型是用于转发的Result,可以将请求转发给JSP.这种类型的Result对应的类为 ServletDispatcherResult,它是St ...

  3. Multiply Strings(字符串乘法模拟,包含了加法模拟)

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  4. Windows平台kafka环境的搭建

    注意:Kafka的运行依赖于Zookeeper,所以在运行Kafka之前我们需要安装并运行Zookeeper 下载安装文件: http://kafka.apache.org/downloads.htm ...

  5. MySQL入门笔记 - 数据类型

    参考书籍<MySQL入门很简单> 数据类型是数据的一种属性,可以决定数据的存储方式.有效范围和相应的限制. 1.整数类型   1.1 MySQL的整数类型 MySQL中int类型和inte ...

  6. (转)Delphi2009初体验 - 语言篇 - 智能指针(Smart Pointer)的实现

     转载:http://www.cnblogs.com/felixYeou/archive/2008/08/27/1277250.html 快速导航 一. 回顾历史二. 智能指针简介三. Delphi中 ...

  7. 【转】Linux下添加新硬盘,分区及挂载

    原文:http://blog.chinaunix.net/uid-25829053-id-3067619.html ------------------------------------------ ...

  8. 第五讲:使用html5中的canvas动态画出物理学上平抛运动

    <html> <head> <title>平抛运动</title> <script src="../js/jscex.jscexRequ ...

  9. Linux经常使用命令(更新中)

    文件类: 1.创建目录:mkdir 例:sudo mkdir test 2.创建空文件:touch 例:sudo touch test.txt 3.删除文件:rm 删除文件不须要确认:rm -f 例: ...

  10. System.Diagnostics.Debug.WriteLine 在OutPut中无输出

    TextWriterTraceListener writer = new TextWriterTraceListener(System.Console.Out);              Debug ...