先说结论: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与线程安全的更多相关文章

  1. Servlet 是否线程安全 看完便知

    Servlet 是否线程安全 看完便知 转自:http://blog.sina.com.cn/s/blog_6448959f0100kct7.html     摘 要:介绍了Servlet多线程机制, ...

  2. 玩转Web之servlet(五)---- 怎样解决servlet的线程安全问题

    servlet默认是存在线程安全问题的,但是说白了,servlet的线程安全问题实际上就是多线程的线程安全问题,因为servlet恰巧是一个多线程才会出现安全性问题. 浏览器每次通过http协议去提交 ...

  3. Servlet的线程安全

    Servlet的线程安全 一.什么是Servlet的线程安全 1.在Servlet的整个生命周期中,构造方法只被执行一次.也就是说,在Servlet的整个生命周期中,只存在一个Servlet实例对象. ...

  4. servlet是线程安全的么

    servlet生命周期 三个重要方法 1  init() 进行资源的加载 2 service() 处理请求,根据请求方式,调用doGet或者doPost 3 destroy() 进行资源的释放 ser ...

  5. 漫画 | Servlet属于线程安全的吗?

    Servlet属于线程安全的吗? Servlet不是线程安全的 在JSP中,只有一行代码:<%=A+B %>,运行结果如何? jsp和servlet有什么关系? jsp一般被用在view层 ...

  6. servlet开发(二)之servlet的线程安全问题

    之所以考虑线程安全问题,是因为引入了多线程.多线程指的是这个程序(一个进程)运行时产生了不止一个线程.如果不考虑多线程的话,程序执行只有一条路径,就像人在敲代码的时候只能敲代码,不能戴上耳机听歌.引入 ...

  7. servlet与线程与jdbc connection的关系

    servlet与线程与jdbc connection的关系 都是一一绑定的关系, servlet接受那么多此请求. 一个请求,对应一个线程,对应一个DB POOL的connection. 因为conn ...

  8. Java面试题:Servlet是线程安全的吗?

    Servlet不是线程安全的. 要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP请求时 ...

  9. servlet 最大线程数探索笔记

    servlet默认是单例模式的,所以是单例多线程的.如果实现了singleservlet是可以多个servlet实例,下面是一个servlet的请求生命周期 1 客户端请求该 Servlet:加载 S ...

  10. Servlet的线程是不是共享同一个requset对象及servlet多线程

    servlet多线程   一,servlet容器如何同时处理多个请求. Servlet采用多线程来处理多个请求同时访问,Servelet容器维护了一个线程池来服务请求.线程池实际上是等待执行代码的一组 ...

随机推荐

  1. django-vue之信息过滤(过滤课程)

    一  vue前端代码 实现的内容,通过对课程的分类,在每个不同的课程分类下显示相应的内容 <template> <div class="course"> & ...

  2. 001-window下运行linux

    一.概述 前提:有条件的情况下,自行安装 在windows上模拟linux环境,主要有三种方法: 1.VMware等虚拟机,缺点:占用系统资源多,运行速度慢. 2.Cygwin等模拟环境,用windo ...

  3. 006-Hadoop Hive sql语法详解1-数据结构和Hive表建立

    1.认识hive:  Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构化的数据文件映射为一张数据库表, ...

  4. Spark2.0机器学习系列之9: 聚类(k-means,Bisecting k-means,Streaming k-means)

    在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法:      (1)K-means      (2)Latent Dirichlet allocation (LDA)  ...

  5. Vi文本编辑

    vi 有3种工作模式,分别是命令行模式.插入模式.底行模式 . 命令行模式:最初进入的一般模式,该模式下可以移动光标进行浏览,整行删除,但无法编辑文字.插入模式:只有在该模式下,用户才能进行文字的编辑 ...

  6. C语言中的extern

    extern: 这个关键字真的比较恶心,在定义变量的时候,extern居然可以被省略(定义时,默认均省略): 在声明变量的时候,extern必须加在变量前. 所以有时候你搞不清楚是声明还是定义.:变量 ...

  7. web.xml中的元素

    error-page元素包含三个子元素error-code,exception-type和location.将错误代码(Error Code)或异常(Exception)的种类对应到web应用资源路径 ...

  8. Bootstrap 中的插件的学习2(导航)

    实例 在导航栏内 下面的实例演示了在导航栏内的下拉菜单的用法: <!DOCTYPE HTML> <html> <head> <link href=" ...

  9. php等守护进程监控脚本(转载 http://www.9958.pw/post/php_script_scan)

    此脚本用户守护监控进程的执行情况,因为有的时候,我们用各类开发语言做的守护进程可能会因为一些特殊情况被退出,所以此脚本就是为了重启这些进程 代码: #!/bin/bash EMAIL='9958_pw ...

  10. Shiro安全框架入门篇

    一.Shiro框架介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和JavaEE项目中都可以使用.它主要用来处理身份认证,授权,企业会话管理和加 ...