繁体   English   中英

在servlet中的init()方法之外声明的变量

[英]Variables declared outside init() method in servlets

我知道对于servlet的每个请求都会执行doPost()或doGet()方法,而init()方法中的代码只会被初始化一次。 但是在所有这些方法之外编写的代码呢?
那个代码还有线程吗? 我的意思是在该部分中声明的变量,如果它们在doPost()被修改,这些变化是否会反映给servlet的其他请求?

在普通的servlet容器中,只有一个servlet对象的实例。 任何数量的线程都可以使用此对象 - 每个请求一个线程。 管理servlet实例的生命周期取决于servlet容器。

因此,在任何方法(包括init())中更改类变量的值时,它将影响所有后续请求。 在您的方法中更改或声明局部变量当然不会影响任何内容,因为下次调用该方法时,会再次创建局部变量(并在方法完成时被垃圾收集器销毁)。

通过defaut Servlets不是线程安全的 将为许多客户端调用单个servlet实例。 将状态存储在servlet中作为实例变量是绝对错误的。

参考文献:

使用session作为实例变量

Servlet是否是线程安全的

编写线程安全的servlet

Servlet实例由容器池化。 因此,任何数量的Servlet对象都可以由真实场景中的任意数量的线程共享。 所有doXXX()方法和从它们调用的其他方法都将由Threads共享。

因此,在Servlet中拥有类级别变量(维护状态)是非常不鼓励的。 虽然您肯定可以使用常量共享的常量,静态辅助方法和静态变量,但不会被使用Servlet的客户端不断修改。

尽管事情是不鼓励的,但是没有阻止你使变量/方法同步。 这将确保一次只有一个线程访问资源,但是由于线程可能必须等待其他人在占用锁之前首先释放资源,因此会有性能损失。

但是有一种更好的方法,如果你希望用Servlet维护状态并希望每个客户端存储变量,你的Servlet应该实现javax.servlet.SingleThreadModel 如果您的Servlet实现了这个标记接口,容器就会知道它维护状态,因此每个实例只能提供一个线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM