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

时间:2012-03-12 10:10:21

标签: java servlets

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

3 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:3)

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

<强>参考文献:

Using session as instance variable

Is a Servlet thread-safe

Write thread safe servlets

答案 2 :(得分:1)

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

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

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

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