servlet线程安全问题

 

我们都知道Servlet是多线程运行的,那么如何让一个Servlet线程安全呢?通常比较常用的措施有如下一些:

1.对于那些特定于某个请求的数据使用局部变量。例如一个登陆应用,每次登陆(也就是一个请求)所采用的用户名和密码可能是不同的,对于这些数据(如用户名、密码)应该使用局部变量来存储,而不应该使用全局变量(即实例变量)

2.只对那些不会发生变化的数据使用全局变量。

3.对于那些可能被某个请求所改变的实例变量要进行保护,譬如,利用synchronize

   关键字对这些数据进行同步,避免多个线程同时修改同一个实例变量的值。

4.如果Servlet需要访问外部资源,如对文件系统进行读写操作,需要对这些外部资源

   的访问进行同步

除此之外,还有2中其它的方法可以让我们的Servlet线程安全,但是这些做法在真实的web应用中不是很实际,而且往往并不能解决我们的问题。

1.使用SingleThreadModel接口,

这是一个标记接口(Marker Interface),它并不包含任何需要实现的方法,如Serializable接口也是这样的一个标记接口。如果servlet实现了这个接口,那么就相当于它告诉了servlet容器这样一个信息:我每次只允许我的一个线程在运行。这时候servlet容器会创建一个servlet实例的池,servlet规范允许servlet容器创建多个实现了SingleThreadModel接口的servlet类的实例。当一个请求到达的时候,容器会从池中取出一个servlet的实例来对请求进行处理,此时如果有其它的请求达到,容器不会为这个servlet实例再创建一个线程来对其进行处理,因为这个servlet已经申明为单线程的了。

但是,这并不能保证我们的servlet线程安全,因为静态变量是所有的变量共享的,除此之外,外部资源也可能被多个请求并发访问,因此如果servlet中使用了静态变量、外部资源等,我们仍需同步对它们的访问。

SingleThreadModel的另外一个确定就是伸缩性太差,因为容器创建的servlet实例的数量是有限的,而且所有的实例都需要进行管理,并发请求的数量越大,这种方法也越不适用,毕竟创建一个新的线程比创建一个新的对象要简单多了。

2.将service()doPost()doGet()等方法同步

这个方法比使用SingleThreadModel更糟糕,如果我们覆盖service方法并将它同步的话,那就意味着,每次我们的servlet每次只能处理一个请求,因为对于那些没有实现SingleThreadModel接口的servlet类,servlet规范仅允许它们的一个实例存在,也就是所谓的单例。如此一来,当多个请求到达的时候,有的客户端会出现等待的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值