Servlet总结04——注意Servlet单实例的线程安全性

探讨了Servlet容器采用单实例多线程方式下变量的安全性问题,通过实例展示了多线程环境下共享变量导致的数据不一致现象,并提供了两种解决方案。

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

Servlet容器采用了单实例多线程的方式(Servlet容器默认的设置),这样可以减少创建实例的开销,提高效率。

但是在多线程方面也埋下了不少隐患,需要开发者格外小心。



(一)变量的安全性

错误实例:

public class test extends HttpServlet{
 
   String user = "" ;
 
   public void doGet(HttpServletRequest req , HttpServletResponse res) throws ServletException , IOException{
     user = req.getParameter( "user" );
     ......
   }
 
}

  例如:a、b同时访问这个servlet,a提交的user=aaa,b提交的user=bbb。

首先,servlet容器分配一个线程T-a来处理请求a,获取其user的值aaa,并赋给变量user。此时T-a时间片到了,servlet容器分配另外一个线程T-b来处理请求b,

获取其user的值bbb,并覆盖变量user,当T-a线程重新获取执行权时,user已经“物是人非”了。

这里可以类比:jdbc的事务管理,“丢失更新”和这个场景类似。
 

解决方案:

1)定义本地变量,将user在doGet方法中定义。

因为user是本地变量,每一个线程都有user变量的拷贝,彼此不受影响。
 

2)设置方法同步(或者同步块)

因为设置了同步,可以防止多个线程同时调用doGet方法。但是所有请求该servlet的“请求”将串行处理,影响效率。


转载地址:http://www.cnblogs.com/huangfox/archive/2011/10/21/2220466.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值