tomct中的stm探索_第1页
tomct中的stm探索_第2页
tomct中的stm探索_第3页
tomct中的stm探索_第4页
tomct中的stm探索_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Tomcat对于SingleThreadModel的分析1 Tomcat介绍在tomcat中一共有4种容器:engine(引擎),host(主机),context(上下文)和 wrapper(包装器)。一个上下文一般包括一个或者多个包装器,每一个包装器表示一个 servlet。首先介绍一个 HTTP 请求会唤醒的一系列方法,接下来介绍了javax.servlet.SingleThreadModel 接口。2 方法调用序列对于每一个连接,连接器都会调用关联容器的 invoke 方法。接下来容器调用它的所有子容器的 invoke 方法.(如上图).上图展示了一个连接器收到一个 HTTP请求的时候会做的一系列事情。1. 请求到达连接器,连接器创建请求和响应对象.2. 连接器调用 StandardContext 的 invoke 方法.并且StandardContext 的 invoke 方法必须调用该上下文容器的流水线的 invoke 方法,所以 StandardContext 的流水线会调用StandardContextValve 的 invoke 方法3. StandardContextValve 的 invoke 方法得到合适的包装器来对请求进行服务并调用包装器的 invoke 方法.(从web.xml中获得该次请求需要使用的servlet信息)4. StandardWrapperValve 的 invoke 方法会调用包装器的 allocate 方法获得一个 servlet 的实例。(如果该servlet实例在tomcat内存中存在, allocate 方法会加载该servlet实例而不是创建.)5. 如果是创建servlet实例,方法 load 会调用 servlet 的 init 方法3 SingleThreadModel一个 servlet 可以实现 javax.servlet.SingleThreadModel 接口.根据 Servlet规范,实现此接口的目的是保证 servlet 一次只能有一个请求。很多程序员并没有仔细阅读它, 只是认为实现了 SIngleThreadModel 就能保证它们的 servlet 是线程安全的。但显然并非如此.请看下文3.1 StandardWrapper一个 StandardWrapper 对象的主要职责是: 加载它表示的 servlet 并分配它的一个实例。在 servlet 第一次被请求的时候,StandardWrapper 加载 servlet 类。它是动态的加载 servlet,所以需要知道 servlet 类的完全限定名称。通过StandardWrapper 类的 setServletClass 方法将 servlet 的类名传递给StandardWrapper(如下图)。StandardWrapper 负责在 StandardWrapperValve 请求的时候分配一个servlet 实例,它必须判断一个 servlet 是否实现了 SingleThreadModel 接口。3.2 Allocate方法如果一个 servlet 没有实现 SingleThreadModel 接口,StandardWrapper 加载该servlet 一次,对于以后的请求返回相同的实例即可。(见下图)对于一个 STM servlet,情况就有所不同了。StandardWrapper 必须保证不能同时有两个线程提交 SingleThreadModel servlet 的 service 方法。如果 StandardWrapper 维持一个 SingleThreadModel servlet 的实例,下面是它如何调用 servlet 的 service 方法:可以看到,使用了同步代码块来保证servlet的service方法调用保持单线程(详见862行处loadServlet方法).显然,真的这样做就意味着你的一个servlet只能同时处理一个请求.所以,为了性能起见,StandardWrapper 维护了一个 SingleThreadModel servlet 实例池(instancePool). 这在下面会详细介绍3.3 Allocating the ServletStandardWrapperValve的invoke方法调用了包装器的allocate 方法来获得一个请求 servlet 的实例。该方法签名如下: public javax.servlet.Servlet allocate() throws ServletException;由于要支持 STM servlet,这使得该方法更复杂了一点。实际上,该方法有两部分组成,一部分负责非 STM servlet 的工作,另一部分负责 STM servlet。基本结构如下(见下图)布尔变量 singleThreadModel 负责标志一个 servlet 是否是 SingleThreadModel servlet。它的初始值是 false,loadServlet 方法会检测加载的 servlet 是否是 STM 的,如果是则将它的值该为 true。现在来看一下第一部分和第二部分。3.3.1 第一部分: 对于非 STM servlet822行来判断是否有相同实例存在于内存中(下图会再次检查).在827行会调用loadServlet方法(下图)创建实例.3.3.2 第二部分:对于STM servlet如果 StandardWrapper 表示的是一个 STM servlet,方法 allocate 尝试返回池中的一个实例,变量 intancePool 是一个 java.util.Stack 类型的 STM servlet实例池。该变量在 loadServlet 方法内初始化方法 allocate 负责分配 STMservlet 实例,前提是实例的数目不超过最大数目,该数目由 maxInstances 整型定义,默认值是 20.(下图)StandardWrapper 提供了 nInstances 整型变量来定义当前 STM 实例的个数。这里是 allocate 方法的第二部分上面的代码使用一个 while 循环等待直到 nInstances 的数目少于或等于countAllocated(应该是多余或等于!)。在循环里,allocate 方法检查nInstance 的值,如果低于 maxInstances 的值,调用 loadServlet 方法并将该实例添加到池中,增加 nInstances 的值。如果 nInstances 的值等于或大于maxInstances 的值,它调用实例池堆栈的 wait 方法,直到一个实例被返回。4 结论分析实现STM接口确实可以保证一个请求对应一个servlet实例.方式就是为每个servlet创建一个容器(栈),当同时有多个请求访问同一个servlet时会尝试从容器中取得servlet实例(如果取完了就会继续创建),当servlet完成任务后,会将servlet放回容器中待命.所以如果一个 Servlet 实现此接口,将保证不会有两个线程同是使用 servlet的 servi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论