`

servlet单实例多线程模式

    博客分类:
  • Java
 
阅读更多

Servlet 的生命周期:

1.        Servlet在 web服务器启动时被加载并实例化,容器运行其 init 方法初始化,请求到达时运行其 service 方法;

2.        service 运行请求对应的 doXXX(doGet,doPost) 方法;

3.        服务器销毁实例,运行其 destory 方法;

Servlet 的生命周期由 Servlet 容器管理;

(三个概念的理解:

Servlet 容器 < Web 容器 < 应用服务器?

Servlet 容器的主要任务就是管理 Servlet 的生命周期;

Web 容器也称之为 web 服务器,主要任务就是管理和部署 web 应用的;

应用服务器的功能非常强大,不仅可以管理和部署 web 应用,也可以部署 EJB 应用,实现容器管理的事务等等。。。

Web 服务器就是跟基于 HTTP 的请求打交道,而 EJB 容器更多是跟数据库,事务管理等服务接口交互,所以应用服务器的功能是很多的。

常见的 web 服务器就是 Tomcat, Tomcat 同样也是 Servlet 服务器;

常见的应用服务器有 WebLogic WebSphere ,但都是收费的;

没有 Servlet 容器,可以用 Web 容器直接访问静态 Html 页面,比如安装了 apache 等;如果需要显示 Jsp/Servlet ,就需要安装一个 Servlet 容器;但是光有 servlet 容器也是不够的,它需要被解析为 html 显示,所以仍需要一个 web 容器;所以,我们常把 web 容器和 Servlet 容器视为一体,因为他们两个容器都有对方的功能实现了,都没有独立的存在了,比如 tomcat

Servlet 是如何处理多个请求同时访问呢?

Servlet 容器默认是采用单实例多线程的方式处理多个请求的:

1.        web 服务器启动的时候(或客户端发送请求到服务器时), Servlet 就被加载并实例化(只存在一个 Servlet 实例);

2.        容器初始化 Servlet 。主要就是读取配置文件(例如 tomcat ,可以通过 servlet.xml <Connector> 设置线程池中线程数目,初始化线程池;通过 web.xml ,初始化每个参数值等等);

3.        当请求到达时, Servlet 容器通过调度线程( Dispatchaer Thread )调度它管理下的线程池中等待执行的线程( Worker Thread )给请求者;

4.        线程执行 Servlet service 方法;

5.        请求结束,放回线程池,等到被调用;

从上面可以看出:

第一: Servlet 单实例,减少了产生 servlet 的开销;

第二:通过线程池来响应多个请求,提高了请求的响应时间;

第三: Servlet 容器并不关心到达的 Servlet 请求访问的是否是同一个 Servlet 还是另一个 Servlet ,直接分配给它一个新的线程;如果是同一个 Servlet 的多个请求,那么 Servlet service 方法将在多线程中并发的执行;

第四:每一个请求由 ServletRequest 对象来接受请求,由 ServletResponse 对象来响应该请求;

问题出现了:

同一个 Servlet 的的多个请求到来时,如果该Servlet中存在成员变量,可能发生多线程同时访问该资源时,都来操作它,造成数据的不一致,因此产生线程安全问题。

解决:

1.        实现 SingleThreadModel 接口

如果一个 Servlet 被这个接口指定 , 那么在这个 Servlet 中的 service 方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题;

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

使用 synchronized 关键字能保证一次只有一个线程可以访问被保护的区段, Servlet 可以通过同步块操作来保证线程的安全。

ServletRequest 对象是线程安全的,但是 ServletContext HttpSession 不是线程安全的;

要使用同步的集合类: Vector 代替 ArrayList HsahTable 代替 HashMap

3.        避免使用实例变量(成员变量)

线程安全问题是由实例变量造成的,只要在 Servlet 里面的任何方法里面都不使用实例变量,那么该 Servlet 就是线程安全的。(所有建议不要在servlet中定义成员变量,尽量用局部变量代替

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

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

分享到:
评论

相关推荐

    servlet多线程

    #### 二、Servlet容器的单实例多线程处理模式 Servlet容器默认采用单实例多线程的方式处理请求,这意味着对于每个Servlet类,容器只会创建一个实例,并让这个实例服务于所有针对该Servlet的请求。这种方式减少了...

    servlet线程安全问题

    Servlet/JSP 技术由于其多线程运行而具有很高的执行效率,但这也意味着需要非常细致地考虑多线程的安全性问题。 Servlet 的多线程机制是建立在 Java 多线程机制之上的。Servlet 容器会自动使用线程池等技术来支持...

    servlet与Struts action线程安全问题分析

    Servlet和Struts Action是两种常见的Java Web开发组件,它们在多线程环境下运行时可能存在线程安全问题。线程安全是指在多线程环境中,一个类或者方法能够正确处理多个线程的并发访问,保证数据的一致性和完整性。 ...

    Web-Servlet_多线程_

    本篇将深入探讨Servlet与多线程的关系,以及如何在Java Web环境中有效地利用多线程。 一、Servlet与多线程基础 Servlet是在Java平台上运行的服务器端组件,主要用于处理HTTP请求。当多个用户同时访问一个Servlet时...

    1工作临时-servlet 多线程问题

    如果Servlet实例是单例模式(默认情况下),那么所有请求都将共享同一个Servlet实例,这就要求开发者必须考虑到线程安全问题,确保在并发环境下代码的正确性。 首先,我们需要理解Java中的线程安全概念。线程安全是...

    tomcat中多线程对于servlet处理的4篇资料

    每个HTTP请求都会分配一个单独的线程,这个线程负责调用Servlet实例的`service`方法。这样设计使得Servlet是无状态的,因为每个请求都有自己的执行线程,避免了线程安全问题。然而,如果Servlet在处理请求时执行了...

    Servlet实例源码

    7. **多线程安全**:由于Servlet容器可能为每个请求创建一个新的线程,因此需要确保源码中的数据操作是线程安全的,避免出现并发问题。 8. **JSP和Servlet协同工作**:在某些实例中,Servlet可能会转发或重定向请求...

    servlet与Struts action线程安全问题分析(pdf)

    Servlet作为一种常用的技术栈,因其多线程运行特性而具备较高的执行效率。然而,这种多线程特性同时也带来了一定程度上的线程安全问题。本文将深入探讨Servlet及其衍生框架Struts中的线程安全问题,并提出相应的解决...

    Servlet线程同步计数器实验

    这意味着在高并发场景下,Servlet实例可能会被多个线程同时访问,如果没有正确处理,就可能导致数据不一致的问题。 线程同步是解决这类问题的关键。在Java中,我们可以使用synchronized关键字、Lock接口(如...

    Servlet线程安全问题.docx

    然而,Servlet在多线程环境下的线程安全问题是一个不容忽视的话题。在Servlet的生命周期中,Tomcat容器会根据需求实例化Servlet并管理其生命周期。当第一个请求到达时,Tomcat会创建Servlet实例,后续的请求将复用同...

    Servlet入门的例子

    对于多线程环境,Servlet容器通常会维护一个Servlet实例池,以提高性能。 7. **Servlet与JSP协同工作** 在实际开发中,Servlet常用于处理业务逻辑,而JSP用于生成动态HTML。Servlet可以设置请求属性,然后转发到...

    servlet是如何同时处理多个请求的

    当我们谈论"Servlet是如何同时处理多个请求的"时,实际上是在讨论Servlet容器(如Tomcat)如何有效地利用多线程来实现并发处理。 在Servlet规范中,每个Servlet实例都有一个生命周期,包括初始化、服务、销毁等阶段...

    利用Servlet求平方根的完美实例

    Servlet是Java Web开发中的一个重要组件,它主要用于处理...如果你对Servlet有了更深入的理解,还可以探索更多高级主题,如多线程处理、异步Servlet、过滤器和监听器等。希望这个实例能成为你学习Servlet的宝贵资料。

    Servlet线程安全的解决方法

    由于Servlet是单例模式实现的,这意味着每次请求都会复用同一个Servlet实例,因此,在多线程环境下,如何确保Servlet的线程安全就显得尤为重要。 #### 二、解决Servlet线程安全问题的方法 针对Servlet线程安全问题...

Global site tag (gtag.js) - Google Analytics