servlet多线程及线程安全(轉載)
Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。当客户端第一次请求某个 Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。 这样,当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致。所以在用Servlet构建的Web应用时如果不注意线程安全的问题,会使所写的Servlet程序有难以发现的错误。
实例变量不正确的使用是造成Servlet线程不安全的主要原因。下面针对该问题给出了三种解决方案并对方案的选取给出了一些参考性的建议。
1、实现 SingleThreadModel 接口
该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要将前面的Concurrent Test类的类头定义更改为:
Public class Concurrent Test extends HttpServlet implements SingleThreadModel {
…………
}
2、同步对共享数据的操作
使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中的Servlet可以通过同步块操作来保证线程的安全。同步后的代码如下:
…………
Public class Concurrent Test extends HttpServlet { …………
Username = request.getParameter ("username");
Synchronized (this){
Output = response.getWriter ();
Try {
Thread. Sleep (5000);
} Catch (Interrupted Exception e){}
output.println("用户名:"+Username+"
");
}
}
}
3、避免使用实例变量
本实例中的线程安全问题是由实例变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。
修正上面的Servlet代码,将实例变量改为局部变量实现同样的功能,代码如下:
……
Public class Concurrent Test extends HttpServlet { public void service (HttpServletRequest request, HttpServletResponse
Response) throws ServletException,IOException {
Print Writer output;
String username;
Response.setContentType ("text/html; charset=gb2312");
……
}
}
对上面的三种方法进行测试,可以表明用它们都能设计出线程安全的Servlet程序。但是,如果一个Servlet实现了 SingleThreadModel接口,Servlet引擎将为每个新的请求创建一个单独的Servlet实例,这将引起大量的系统开销。 SingleThreadModel在Servlet2.4中已不再提倡使用;同样如果在程序中使用同步来保护要使用的共享的数据,也会使系统的性能大大下降。这是因为被同步的代码块在同一时刻只能有一个线程执行它,使得其同时处理客户请求的吞吐量降低,而且很多客户处于阻塞状态。另外为保证主存内容和线程的工作内存中的数据的一致性,要频繁地刷新缓存,这也会大大地影响系统的性能。所以在实际的开发中也应避免或最小化 Servlet 中的同步代码;在Serlet中避免使用实例变量是保证Servlet线程安全的最佳选择。从Java 内存模型也可以知道,方法中的临时变量是在栈上分配空间,而且每个线程都有自己私有的栈空间,所以它们不会影响线程的安全。
分享到:
相关推荐
Servlet 线程安全问题是指在使用 Servlet 编程时,如果不注意多线程安全性问题,可能会导致难以发现的错误。Servlet/JSP 技术由于其多线程运行而具有很高的执行效率,但这也意味着需要非常细致地考虑多线程的安全性...
#### 二、Servlet多线程原理 Servlet架构基于Java多线程机制。当客户端首次请求某个Servlet时,Web容器会根据`web.xml`配置文件实例化该Servlet。之后对于相同的Servlet请求,容器通常不会重新实例化,而是复用现有...
### servlet多线程详解 #### 一、Servlet容器如何同时处理多个请求 Servlet容器通过采用多线程机制来实现对多个请求的同时处理。这一过程主要依赖于容器内部维护的一个线程池,它由一系列处于待命状态的工作线程...
Servlet和Struts Action是两种常见的Java Web开发组件,它们在多线程环境下运行时可能存在线程安全问题。线程安全是指在多线程环境中,一个类或者方法能够正确处理多个线程的并发访问,保证数据的一致性和完整性。 ...
至于提供的文件"8点25分平安大厦集合旅游人员名单.xls",虽然与Servlet多线程问题无关,但可能是某个实际应用场景中涉及的数据或计划,比如用于统计并发访问的用户信息,或者是记录多线程处理过程中的某些状态信息。...
本篇将深入探讨Servlet与多线程的关系,以及如何在Java Web环境中有效地利用多线程。 一、Servlet与多线程基础 Servlet是在Java平台上运行的服务器端组件,主要用于处理HTTP请求。当多个用户同时访问一个Servlet时...
由于Servlet是单例模式实现的,这意味着每次请求都会复用同一个Servlet实例,因此,在多线程环境下,如何确保Servlet的线程安全就显得尤为重要。 #### 二、解决Servlet线程安全问题的方法 针对Servlet线程安全问题...
Servlet是一种线程不安全的组件,它的线程不安全性体现在多线程环境下共享一个实例变量,导致线程安全问题。下面我们将从Servlet的工作原理说起,详细解释Servlet接收和响应客户请求的过程,并探讨Servlet线程不安全...
然而,Servlet在多线程环境下的线程安全问题是一个不容忽视的话题。在Servlet的生命周期中,Tomcat容器会根据需求实例化Servlet并管理其生命周期。当第一个请求到达时,Tomcat会创建Servlet实例,后续的请求将复用同...
Java_servlet多线程.pdf
然而,这种多线程特性同时也带来了线程安全性的问题,特别是当Servlet中的实例变量被多个线程共享时。本文旨在深入探讨Servlet线程安全性问题及其解决策略。 #### 二、Servlet的多线程机制 Servlet容器(如Tomcat...
Servlet作为Java服务器端组件,其默认的多线程模型使得一个Servlet实例可能会被多个客户端请求同时调用,这就要求开发者对线程安全有深入的理解,以避免潜在的数据不一致性和其他并发问题。 Servlet的多线程机制...
在这个主题中,我们将深入探讨"Tomcat中多线程对于Servlet处理"的相关知识点,特别关注在5.5.17版本中的实现。 1. **Tomcat的线程模型** Tomcat使用了一个基于Apache Commons Daemon的JVM服务模型,其中包含了...
Servlet线程同步计数器实验是Java Web开发中一个重要的实践课题,主要涉及到Servlet容器如何处理并发请求以及如何确保在多线程环境下的数据一致性。在这个实验中,我们将深入理解Servlet生命周期、线程模型以及线程...