论坛首页 入门讨论版 Java

[讨论]容器启动后,会有几个servlet实例?

浏览 1120 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2007-10-19 关键字: servlet
上次面试时,问了个如果多用户并发访问servlet时,该如何解决.当时想的是好像是由Web容器解决的吧.
后来他再问句如果多个用户访问servlet,容器中会有几个实例,这个就一点也清楚了,随便猜了说1个(有点主观)
后来到网上查了下,结果如下:
-------------------------
一般来说servlet是线程安全的,所以每个用户每一次的调用都是独立的

当一个SERVLET被创建并且被装载到内存,它在内存中仅有一个实例,采用多线程去访问这个SERVLET实例

----------------------------
再后来自己做了个实验,  http://laorer.javaeye.com/admin/show/132771
实验的思路如下:
---
在servlet中定义了一个整型的类变量(没有进行同步操作,可以粗略的存储被请求的次数)还有整型的实例变量(也没有进行同步操作,用这个来判定是否与类变量相等,相等则只有一个实例,不等应该有多个实例)
-----
实验结果证明上面那个说法的正确性,本来也就没事了,但今天无意看到一个servlet2.3规范,便看了下,
说法是这样的.
------------
For a servlet not hosted in a distributed environment (the default), the servlet container must use only one instance per servlet declaration. However, for a servlet implementing the SingleThreadModel interface, the servlet container may instantiate multiple instances to handle a heavy request load and serialize requests
to a particular instance.

In the case where a servlet was deployed as part of an application marked in
the deployment descriptor as distributable, a container may have only one instance
per servlet declaration per virtual machine (VM). However, if the servlet in a dis-
tributable application implements the SingleThreadModel interface, the container may instantiate multiple instances of that servlet in each VM of the container.

-------------------
也找了一份中文规范,不过感觉翻得不太好就不帖出来了

说是如果实现了SingleThreadModel 接口,则可能会有多个实例.便实验了一下,出现的结果不知道怎么解释,实验的方法和前面一样,不过servlet实现了SingleThreadModel 接口.
结果是每刷一次 类变量增加一次,这个没问题,但是每刷五次,实例变量才增加一次,而且多个浏览器访问的时候,当一个实例变量增加了,其他浏览器的实例变量也增加, 这点就不清楚为什么了,开始以为是容器中有五个实例,但后来想想不对,每个浏览器的实例应该不一样的,所以为什么一个浏览器请求的值变化了,其他浏览器请求的值也会变了呢

实验环境是  eclipse3.2(估计和这没关系) + Weblogic 8.1 + jdk 1.4
   
最后更新时间:2007-10-19
请问下规范的出处,谢谢
   
0 请登录后投票
最后更新时间:2007-10-19
还有,servlet的线程安全也要建立在你没有类变量的基础上,如果有类变量,且只有一个实例,怎么都安全不了
   
0 请登录后投票
最后更新时间:2007-10-19
http://www.orionserver.com/docs/specifications/servlet-2_3-fcs-spec.pdf

应该不会有错

在第二章吧  The Servlet Interface 的 SRV2.2 Number of Instances 里
   
0 请登录后投票
最后更新时间:2007-10-19
wf_chn 写道
还有,servlet的线程安全也要建立在你没有类变量的基础上,如果有类变量,且只有一个实例,怎么都安全不了

有类变量也只有通过 同步 来控制了,

但实例变量就不一样了,如果有多个实例的话,则应该每个浏览器所请求的实例变量值不太可能会一样啊,或者说应该是各自独立的.除非他们请求的是同一个实例,但请求的是同一个实例,则应实例变量本身应该是自增的
   
0 请登录后投票
最后更新时间:2007-10-19
sorry,我弄错了,我想说的就是普通的实例变量
因为只有一个实例,除非大家都约定不去动这些成员,否则是安全不了的
还有,我不懂你所说的实例变量本身是自增的是什么意思
   
0 请登录后投票
最后更新时间:2007-10-19
我在实验中,将实例变量设为 int 型 ,每访问一次就自增一次,所以你说的那种 大家都约定不去动这些成员 就不可能了.

因为我就是想看下容器中到底有几个实例,只有一个实例的话,非并发状态下所有浏览器的请求总体上肯定是顺序的,
如果有多个实例,每个浏览浏览器的请求就不会在总体上顺序了,(不知道假设有没有错误)

并发安全问题我想最好不在这里考虑,一般的并发安全性主要还是数据库访问吧,所以那个留下后一层次来解决, servlet本身的成员变量的非要解决的话,似乎也只有用同步了.
   
0 请登录后投票
最后更新时间:2007-10-19
看了你的试验,大概有点明白你的意思了
你的假设应该是正确的
刚才看了那份spec,和我以前看到一些说法有冲突
但至少证明了,只要符合规范的都是一个实例
但是还需要考虑serlvet的生命周期的问题,spec没规定何时destroy实例,所以用servlet的实例变量来计数的话还是有风险的

至于并发安全,那就是不能要实例变量了,如果需要共享信息,得依赖其他办法了
   
0 请登录后投票
最后更新时间:2007-10-19
wf_chn 写道
看了你的试验,大概有点明白你的意思了
刚才看了那份spec,和我以前看到一些说法有冲突
但至少证明了,只要符合规范的都是一个实例

the servlet container may instantiate multiple instances to handle a heavy request load and serialize requests to a particular instance.
这里不是说可以有多个实例吗?
wf_chn 写道

但是还需要考虑serlvet的生命周期的问题,spec没规定何时destroy实例,所以用servlet的实例变量来计数的话还是有风险的
至于并发安全,那就是不能要实例变量了,如果需要共享信息,得依赖其他办法了

计数应该不会用这种办法了,应该在其他层中考虑,

但是第二个实验中,不懂为什么实例变量在请求五次之后才增加一次
   
0 请登录后投票
最后更新时间:2007-10-19
不好意思,我没做过分布式的,所以才这么认为,至于分布式的情况,我不会,也不去设想这种情况下的问题了

至于第二个试验,应该有多个实例,出现令人不解的结果应该和调度有关了,至于里面怎么调度,要去问JVM了
   
0 请登录后投票
论坛首页 入门讨论版 Java

跳转论坛:
JavaEye推荐