先说结论: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. Pycharm配置同步服务器

    一.使用场景 我们一般需要将代码放到服务器上运行,但如果等我们将项目全部开发好之后再上传到服务器,而且每次在开发阶段需要经过多次修改,每修改一次,都手动上传一次,这样就太麻烦了,有没有一种方法可以达到 ...

  2. 需求-shidebing

    # 原始数据 list1 = [ {"c_id": "101", "e_code": "201"}, {"c_ ...

  3. libx264 安卓编译

    https://github.com/RoyGuanyu/build-scripts-of-ffmpeg-x264-for-android-ndk/blob/master/ffmpeg/build_a ...

  4. RNNs

    什么是RNN网络? RNNs背后的主要目的是要使用序列本身的顺序信息.在传统的神经网络里,我们假设输入(输出)是条件独立的.但是,在许多任务里,这是个非常非常差的假设.如果你想预测一个序列中的下一个单 ...

  5. (转)VC串口小程序(用SerialPort类)

    ××××××××××××××××××××××××××××××××××××××××××××××××××××× 在MFC里面实现串口通讯有很多方式: 方案一:使用微软公司提供的 串口类,SerialPor ...

  6. python字符串的操作(去掉空格strip(),切片,查找,连接join(),分割split(),转换首字母大写, 转换字母大小写...)

    #可变变量:list, 字典#不可变变量:元祖,字符串字符串的操作(去掉空格, 切片, 查找, 连接, 分割, 转换首字母大写, 转换字母大小写, 判断是否是数字字母, 成员运算符(in / not ...

  7. Web UI 自动化单个xpath抓取插件详解

    原文地址http://blog.csdn.net/kaka1121/article/details/51878346 单个控件获取 需求: 右键到某个控件上,就能获取到至多三个可以唯一定位该元素的相对 ...

  8. Shiro安全框架入门篇

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

  9. Divide by Zero 2017 and Codeforces Round #399 (Div. 1 + Div. 2, combined) D. Jon and Orbs

    地址:http://codeforces.com/contest/768/problem/D 题目: D. Jon and Orbs time limit per test 2 seconds mem ...

  10. python3_configparser模块详解

    主要介绍python3中的ConfigParser模块的使用,该模块主要被用来读写配置文件. 安装模块:pip3 install configparser root@ranxf:/usr/lib/py ...