多个用户访问服务器同一个servlet是访问一个servelt实例还是多个?

_忆_ 发布于 2013/08/09 11:11
阅读 5K+
收藏 2
多个用户访问服务器同一个servlet是访问一个servelt实例还是多个?
加载中
0
红薯
红薯
Servlet 是单实例的
0
_忆_
_忆_
怎么防止多个用户访问的冲突问题
红薯
红薯
不会有冲突,只要不要在 servlet 中使用实例变量
0
_忆_
_忆_
可能会冲突啊,因为serlvet如果有根据不用用户得到不同的数据返回给客户端,如果前一个用户进来后,后一个用户也进来,servlet中他会根据后一个用户得到后一个用户的数据返回
0
你若安好
你若安好
讲得不清楚,用户应该是根据一个标识来获取数据 只要用户标识不一样不会获取到相同的数据!不同用户调用的serlvet不是同一个会重新实例化一个新的
0
Jeky
Jeky

1、Servlet是单实例,LS不知道可以不说,别误导新人

2、只要Servlet里没有实例变量,就不会产生冲突问题,你所想的那种情况只是自己想的,实际情况是每个用户走的流程互不冲突

0
俏文安
俏文安

servlet 是单实例,多线程访问,所以要做线程安全的处理,尽量避免全局变量。

还有一个方法是实现 singlethreadmodel,这样就能保证线程安全了,但是性能下降的比较厉害。

0
专业打酱油
专业打酱油

引用来自“_忆_”的答案

可能会冲突啊,因为serlvet如果有根据不用用户得到不同的数据返回给客户端,如果前一个用户进来后,后一个用户也进来,servlet中他会根据后一个用户得到后一个用户的数据返回

1:serlvet是单实例的。

解释:在web容器中,比如tomcat(命名为A)中,一个web(命名B)应用中,有一个UserServlet,这个UserServlet是一个单例,也就是说,在这个A的B中有且仅有一个UserServlet。

2:UserSerlvet接受UserId,返回UserName,多个用户访问的时候,是多个线程在运行,你说的前一个用户,后一个用户,对应多个线程。用户=线程,暂时这么理解吧。

比如你说的例子:

id=1 name=jack

id=2 name=tom

线程1访问了UserServet,接受到UserId为1,并没有返回UserName,线程1未结束

线程2访问了UserServet,接受到UserId为2,查询结果,返回UserName=Tom,线程2结束

线程1查询结果,返回什么?返回jack

因为线程1和线程2是两个独立的线程,接受到Userid为线程内部方法的局部变量,根据id查询出来的UserName,有效范围也仅在每个线程的查询方法内有效!(前提条件是UserName是方法的局部变量,不要把UserName声明成实例变量!!)

线程1不能获得线程2的UserId=2,也不能获得线程2的UserName=Tom。

因为UserId,UserName的声明,都在Servlet的方法内部,(如果你放到方法外面,就会有问题),

每个线程都会有自己的UserId,UserName,存在VM Stack中,方法结束,线程结束,这些UserId,UserName,失去与GCRoot的联系,会等待被GC回收,最终被清除。

综上:

多个用户访问同一个Servlet的时候,会不会出现冲突,取决于访问的Servlet的方法里面是否有Servlet的实例变量,如果有,多个用户共享这个实例变量,如果没有则互不影响,各回各家,各找各妈。

如果没看懂或不明白:在Servlet中尽量不要使用自定义的实例变量!




专业打酱油
专业打酱油
回复 @冷月孤寒 : 那要学习一下了。
咯咯鸡
咯咯鸡
对头,另外《Head First Servlet & JSP》中也写得很清楚
0
sxgkwei
sxgkwei

只要不在servlet类里面声明任何属性,然后用这些属性来持有临时数据,只写方法,而所有的持有数据的变量声明都是在方法内部,就不会“串”掉的。

这种时候,你可以理解为,方法被”复制“出来了一份,每个用户进入的是各自”复制“的方法。互补影响。

0
云香水识
云香水识

引用来自“专业打酱油”的答案

引用来自“_忆_”的答案

可能会冲突啊,因为serlvet如果有根据不用用户得到不同的数据返回给客户端,如果前一个用户进来后,后一个用户也进来,servlet中他会根据后一个用户得到后一个用户的数据返回

1:serlvet是单实例的。

解释:在web容器中,比如tomcat(命名为A)中,一个web(命名B)应用中,有一个UserServlet,这个UserServlet是一个单例,也就是说,在这个A的B中有且仅有一个UserServlet。

2:UserSerlvet接受UserId,返回UserName,多个用户访问的时候,是多个线程在运行,你说的前一个用户,后一个用户,对应多个线程。用户=线程,暂时这么理解吧。

比如你说的例子:

id=1 name=jack

id=2 name=tom

线程1访问了UserServet,接受到UserId为1,并没有返回UserName,线程1未结束

线程2访问了UserServet,接受到UserId为2,查询结果,返回UserName=Tom,线程2结束

线程1查询结果,返回什么?返回jack

因为线程1和线程2是两个独立的线程,接受到Userid为线程内部方法的局部变量,根据id查询出来的UserName,有效范围也仅在每个线程的查询方法内有效!(前提条件是UserName是方法的局部变量,不要把UserName声明成实例变量!!)

线程1不能获得线程2的UserId=2,也不能获得线程2的UserName=Tom。

因为UserId,UserName的声明,都在Servlet的方法内部,(如果你放到方法外面,就会有问题),

每个线程都会有自己的UserId,UserName,存在VM Stack中,方法结束,线程结束,这些UserId,UserName,失去与GCRoot的联系,会等待被GC回收,最终被清除。

综上:

多个用户访问同一个Servlet的时候,会不会出现冲突,取决于访问的Servlet的方法里面是否有Servlet的实例变量,如果有,多个用户共享这个实例变量,如果没有则互不影响,各回各家,各找各妈。

如果没看懂或不明白:在Servlet中尽量不要使用自定义的实例变量!




讲得很透彻啊! 顶一下。
0
pandyyan
pandyyan
只有存在共享变量(实例变量)的情况下,才需要考虑多线程安全的问题,方法参数、内部变量都是线程私有的,不会对其他线程产生影响,所以不使用实例变量的情况下,Servlet是线程安全的,否则就需要实现 SingleThreadModel 接口或者使用synchronized控制多线程的并发。
返回顶部
顶部