Servlet的多线程 和 Servlet线程安全

本文深入解析JSP/Servlet的多线程机制,包括如何通过多线程减少资源消耗、提高并发量与响应速度,并详细阐述了不同组件如Servlet实例、线程、Application对象、ServletContext、HttpServletRequest、HttpServletResponse和HttpSession的线程安全性。同时,文章还提供了解决线程安全问题的常见方法,如使用局部变量、同步语句和同步集合类等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSP/Servlet的多线程原理:
  • 1.servelet就是一个CGI,但比传统的CGI要快得过
传统CGI是多进程的,servlet是多线程的
以多线程方式执行可大大降低对系统的资源需求,提高 系统的并发量及响应时间.
  • JSP/Servlet容器默认是采用单实例多线程(这是造成线程安全的主因)方式处理多个请求的:
当客户端第一次请求某一个JSP文件时(有的servlet是随容器启动就startup):
  1. 服务端把该JSP编译成一个CLASS文件
  2. 并创建一个该类的实例
  3. 然后创建一个线程处理CLIENT端的请求。
  • 多请求,多线程:
如果有多个客户端同时请求该JSP文件,则服务端会创建多个线程。每个客户端请求对应一个线程。




servlet 的线程安全
  • servlet里的 实例变量
servlet里的实例变量,是 被所有线程共享的,所以不是线程安全的.
  • servlet方法里的局部变量
因为每个线程都有它自己的堆栈空间,方法内局部变量存储在这个线程堆栈空间内,
且参数传入方法是按传值volue copy的方式
所以是线程安全的
  • Application对象
在container运行期间,被整个系统内所有用户共同使用,所以不是线程安全 的
  • ServletContext对象
ServletContext是可以多线程同时读/写属性的,线程是不安全的
struts2的ServletContext采用的是TreadLocal模式,是线程安全的
  • HttpServletRequest对象和HttpServletResponse对象
每一个请求,由一个工作线程来执行,都会 创建有一对新的ServletRequest对象和ServletResponse,然后传入service()方法内
所以每个ServletRequest对象对应每个线程,而不是多线程共享,是线程安全的。所以不用担心request参数和属性的线程安全性
  • HttpSession
Session对象在用户session期间存在, 只能在属于同一个SessionID的请求的线程中被访问,因此Session对象的理论上是线程安全的。
(当用户打开多个同属于一个进程的浏览器窗口(常见的弹出窗口),在这些窗口的访问属于同一个Session,会出现多次请求,需要多个工作线程来处理请求,这时就有可能的出现线程安全问题)

<wbr><br><br><span style="font-weight:bold">servlet尽量用方法内变量,就一定线程安全么?<wbr>局部变量的数据也来自request对象或session对象啊,它们线程安全么?</wbr></span><br> servletRequest 线程是安全的<br> 因为:每个 request都会创建一个新线程,每个新线程,容器又都会创建一对servletRequest和servletResponse对象(这是servlet基本原理)<br> 所以servletRequest对象和servletResponse对象只在一个线程内被创建,存在,被访问<br><br><br><br><span style="font-weight:bold">常见的线程安全的解决办法:</span><br> 1.使用方法内局部变量<br><ul> <li>是因为各线程有自己堆栈空间,存储局部变量</li> <li>方法参数传入,多采用传值(volue copy)传入方法内</li> </ul> <br> 2.对<span style="font-weight:bold">操作共享资源</span>的语句,方法,对象,使用同步<br> 比如<span style="font-weight:bold">写入磁盘文件</span>,采用同步锁,但建议尽量用同步代码块,不要用同步方法<br><br><br> 3.使用同步的集合类<br> 使用Vector代替ArrayList<br> 使用Hashtable代替HashMap。<br><br> 4.不要在 Servlet中再创建自己的线程来完成某个功能。<br> Servlet本身就是多线程的,在Servlet中再创建线程,将导致执行情况复杂化<br><br> 原文地址:http://blog.sina.com.cn/s/blog_6151984a0100khbf.html<br></wbr>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值