|
精华帖 (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 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2007-10-19
请问下规范的出处,谢谢
|
|
| 返回顶楼 | |
|
最后更新时间:2007-10-19
还有,servlet的线程安全也要建立在你没有类变量的基础上,如果有类变量,且只有一个实例,怎么都安全不了
|
|
| 返回顶楼 | |
|
最后更新时间:2007-10-19
http://www.orionserver.com/docs/specifications/servlet-2_3-fcs-spec.pdf
应该不会有错 在第二章吧 The Servlet Interface 的 SRV2.2 Number of Instances 里 |
|
| 返回顶楼 | |
|
最后更新时间:2007-10-19
wf_chn 写道 还有,servlet的线程安全也要建立在你没有类变量的基础上,如果有类变量,且只有一个实例,怎么都安全不了
有类变量也只有通过 同步 来控制了, 但实例变量就不一样了,如果有多个实例的话,则应该每个浏览器所请求的实例变量值不太可能会一样啊,或者说应该是各自独立的.除非他们请求的是同一个实例,但请求的是同一个实例,则应实例变量本身应该是自增的 |
|
| 返回顶楼 | |
|
最后更新时间:2007-10-19
sorry,我弄错了,我想说的就是普通的实例变量
因为只有一个实例,除非大家都约定不去动这些成员,否则是安全不了的 还有,我不懂你所说的实例变量本身是自增的是什么意思 |
|
| 返回顶楼 | |
|
最后更新时间:2007-10-19
我在实验中,将实例变量设为 int 型 ,每访问一次就自增一次,所以你说的那种 大家都约定不去动这些成员 就不可能了.
因为我就是想看下容器中到底有几个实例,只有一个实例的话,非并发状态下所有浏览器的请求总体上肯定是顺序的, 如果有多个实例,每个浏览浏览器的请求就不会在总体上顺序了,(不知道假设有没有错误) 并发安全问题我想最好不在这里考虑,一般的并发安全性主要还是数据库访问吧,所以那个留下后一层次来解决, servlet本身的成员变量的非要解决的话,似乎也只有用同步了. |
|
| 返回顶楼 | |
|
最后更新时间:2007-10-19
看了你的试验,大概有点明白你的意思了
你的假设应该是正确的 刚才看了那份spec,和我以前看到一些说法有冲突 但至少证明了,只要符合规范的都是一个实例 但是还需要考虑serlvet的生命周期的问题,spec没规定何时destroy实例,所以用servlet的实例变量来计数的话还是有风险的 至于并发安全,那就是不能要实例变量了,如果需要共享信息,得依赖其他办法了 |
|
| 返回顶楼 | |
|
最后更新时间: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的实例变量来计数的话还是有风险的 至于并发安全,那就是不能要实例变量了,如果需要共享信息,得依赖其他办法了 计数应该不会用这种办法了,应该在其他层中考虑, 但是第二个实验中,不懂为什么实例变量在请求五次之后才增加一次 |
|
| 返回顶楼 | |
|
最后更新时间:2007-10-19
不好意思,我没做过分布式的,所以才这么认为,至于分布式的情况,我不会,也不去设想这种情况下的问题了
至于第二个试验,应该有多个实例,出现令人不解的结果应该和调度有关了,至于里面怎么调度,要去问JVM了 |
|
| 返回顶楼 | |




