简体   繁体   English

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

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

I know that for each request to a servlet a the doPost() or doGet() methods are executed and that the code wirtten inside init() method is initialised only once. 我知道对于servlet的每个请求都会执行doPost()或doGet()方法,而init()方法中的代码只会被初始化一次。 But what about the code written outside all these methods? 但是在所有这些方法之外编写的代码呢?
Is that code also threaded? 那个代码还有线程吗? I mean varibles declared in that part, if they are modified in the doPost() , will those changes be reflected for other requsts to the servlets? 我的意思是在该部分中声明的变量,如果它们在doPost()被修改,这些变化是否会反映给servlet的其他请求?

In a normal servlet container, there is only one instance of the servlet object. 在普通的servlet容器中,只有一个servlet对象的实例。 This object may be used by any number of Threads - one Thread per request. 任何数量的线程都可以使用此对象 - 每个请求一个线程。 Managing the lifetime of a servlet instance is up to the servlet container. 管理servlet实例的生命周期取决于servlet容器。

Hence, when changing the value of a class variable in any method (including init()), it will affect all subsequent requests. 因此,在任何方法(包括init())中更改类变量的值时,它将影响所有后续请求。 Changing or declaring a local variable within your method of course does not influence anything, as the next time the method is called, the local variable is created again (and gets destroyed by the garbage collector when the method is finished). 在您的方法中更改或声明局部变量当然不会影响任何内容,因为下次调用该方法时,会再次创建局部变量(并在方法完成时被垃圾收集器销毁)。

By defaut Servlets are not thread safe . 通过defaut Servlets不是线程安全的 A single servlet instance will be invoked for many clients. 将为许多客户端调用单个servlet实例。 It is absolutely wrong to have state stored inside the servlet as instance variables. 将状态存储在servlet中作为实例变量是绝对错误的。

References: 参考文献:

Using session as instance variable 使用session作为实例变量

Is a Servlet thread-safe Servlet是否是线程安全的

Write thread safe servlets 编写线程安全的servlet

Servlets instances are pooled by the container. Servlet实例由容器池化。 So any number of Servlet Objects can be shared by any number of threads in the real world scenario. 因此,任何数量的Servlet对象都可以由真实场景中的任意数量的线程共享。 All the doXXX() methods and other methods called from them will be shared by Threads. 所有doXXX()方法和从它们调用的其他方法都将由Threads共享。

Hence it is highly discouraged to have class level variables (to maintain state) in Servlets. 因此,在Servlet中拥有类级别变量(维护状态)是非常不鼓励的。 Although you can surely have Constants, Static helper methods and static variables which are shared by instances also and not constantly modified by clients using the Servlet. 虽然您肯定可以使用常量共享的常量,静态辅助方法和静态变量,但不会被使用Servlet的客户端不断修改。

Although things are discouraged, but there is no stopping you from making the variables/methods synchronized. 尽管事情是不鼓励的,但是没有阻止你使变量/方法同步。 This would ensure that only one thread accesses the resource at a time, but there would be a performance penalty as Threads might have to wait for others to release the resource first before occupying a lock. 这将确保一次只有一个线程访问资源,但是由于线程可能必须等待其他人在占用锁之前首先释放资源,因此会有性能损失。

But there is a better way, In case you wish to maintain state with a Servlet and want to store variables per client, Your Servlet should implement javax.servlet.SingleThreadModel . 但是有一种更好的方法,如果你希望用Servlet维护状态并希望每个客户端存储变量,你的Servlet应该实现javax.servlet.SingleThreadModel If your Servlet implements this marker interface, container would know that it maintains state and hence only one thread would be served per instance. 如果您的Servlet实现了这个标记接口,容器就会知道它维护状态,因此每个实例只能提供一个线程。

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

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