Servlet线程安全的解决方法

开发 后端
当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致,所以就很容易造成一系列的一些安全性问题。

Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。

当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。

这样的话,当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致,所以就很容易造成一系列的一些安全性问题。

解决此类的方法也有多

1、实现 SingleThreadModel 接口

该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要继承这个接口就行了

  1. public class XXXXX extends HttpServlet implements SingleThreadModel {  
  2. …………  

2、同步对共享数据的操作

使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中可以通过同步块操作来保证Servlet的线程安全。同步后的代码如下:

  1. Public class XXXXXX extends HttpServlet {  
  2.     …………  
  3. synchronized (this){XXXX}  
  4.  

3、避免使用实例变量

线程安全问题还有些是由实例变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。

对上面的三种方法进行测试,可以表明用它们都能设计出线程安全的Servlet程序。但是,如果一个Servlet实现了SingleThreadModel接口,Servlet引擎将为每个新的请求创建一个单独的Servlet实例,这将引起大量的系统开销。SingleThreadModel在Servlet2.4中已不再提倡使用;同样如果在程序中使用同步来保护要使用的共享的数据,也会使系统的性能大大下降。这是因为被同步的代码块在同一时刻只能有一个线程执行它,使得其同时处理客户请求的吞吐量降低,而且很多客户处于阻塞状态。另外为保证主存内容和线程的工作内存中的数据的一致性,要频繁地刷新缓存,这也会大大地影响系统的性能。所以在实际的开发中也应避免或最小化Servlet 中的同步代码;在Serlet中避免使用实例变量是保证Servlet线程安全的最佳选择。从Java 内存模型也可以知道,方法中的临时变量是在栈上分配空间,而且每个线程都有自己私有的栈空间,所以它们不会影响线程的安全。

小结

Servlet的线程安全问题只有在大量的并发访问时才会显现出来,并且很难发现,因此在编写Servlet程序时要特别注意。线程安全问题主要是由实例变量造成的,因此在Servlet中应避免使用实例变量。如果应用程序设计无法避免使用实例变量,那么使用同步来保护要使用的实例变量,但为保证系统的最佳性能,应该同步可用性最小的代码路径。

【编辑推荐】

  1. JSP+JavaBean+Servlet结构工作原理浅析
  2. Servlet页面跳转实现方法的区别
  3. Servlet多线程的相关问题浅析
  4. Servlet容器之安全多线程问题
  5. JSP Servlet开发最初那点事
责任编辑:雪峰 来源: CSDN博客
相关推荐

2009-07-03 18:13:28

Servlet线程安全

2009-07-24 10:42:28

CLR线程池

2016-09-23 20:46:53

2023-08-02 07:39:07

多线程开发资源

2010-03-22 10:59:24

Java Socket

2016-04-20 18:40:23

2010-07-29 15:28:47

Flex安全沙箱

2010-07-15 14:01:12

telnet乱码

2009-07-03 16:53:11

Servlet容器

2010-08-03 09:12:52

Flex安全沙箱

2011-03-01 13:40:45

500 OOPS

2009-12-17 10:09:02

ssh超时断开

2023-04-06 15:21:34

IIoT自动化

2010-10-13 17:22:12

MySQL查询乱码

2009-09-10 09:35:25

Linq语句

2010-04-20 16:46:41

Oracle数据库密码

2010-07-29 15:44:54

Flex安全沙箱

2011-05-18 14:00:30

在线备份

2023-10-26 08:16:20

C++线程

2010-06-17 10:32:13

开机显示Grub
点赞
收藏

51CTO技术栈公众号