本问题已经有最佳答案,请猛点这里访问。
HttpServletRequest request;
HttpServletResponse response;
public void doGet(HttpServletRequest request , HttpServlet response){
this.request = request;
this.response = response;
}
如果此servlet一次收到多个请求会发生什么?
我们遇到了响应不匹配的问题。 这是一个问题吗?
不要这样做。 真。 别。
这使得世界陷入了黑洞
了解servlet的工作原理:stackoverflow.com/questions/3106452/
您的Web应用程序容器仅加载一个servlet实例。
要编写线程安全的servlet,你几乎不应该使用实例变量。将请求和响应设置为实例变量是完全错误的。 servlet的实例不属于单个请求。
如果您需要将请求或响应的元素提供给其他方法,请将它们传递给这些方法。您不需要它们作为实例变量。
尝试编写一个没有实例变量的非平凡servlet; servlet必须在某些时候(即服务)将控制权委托给某事物。你的意思是不使用非线程安全的实例变量。
当然这是一个问题。 servlet是一个单例。相同的servlet实例用于处理对此servlet的所有请求。并且请求当然是同时处理的。这意味着如果你这样做,thread1将使用通常由thread2处理的请求和响应。
根据定义,Servlet不是单身人士。 Servlet API不会将特定Servlet类的创建限制为单个实例。 Container通常会为部署描述符中的每个servlet声明创建一个servlet实例。单例是一种设计模式,它将其类的对象的创建限制为1且仅为1。
它们不是GoF模式意义上的单例,但它们是有效的,因为servlet规范要求容器只为每个servlet声明实例化一个实例。单例不仅仅是GoF设计模式。你曾经使用像Spring或Guice这样的依赖注入框架吗?在这种情况下从未见过单身人士?
是的,我有。我试图与GoFs对单身人士的定义联系起来。并加上1为您的详细说明:)
所以你选择了一个特定的singleton定义,并决定servlet没有遵循这个特定的定义,因此不是单身人士?这就像说免费啤酒不是免费的,因为它甚至没有开源许可证。
引用Servlet规范
"每个请求和响应对象仅在servlet的服务方法范围内有效,或者在过滤器的doFilter方法范围内有效。容器通常是回收的
请求对象以避免请求对象的性能开销
创建。开发人员必须意识到维护对请求对象的引用
不建议在上述范围之外,因为它可能具有不确定性
结果。"
这与OPs问题没有太大关系。如果他在doGet()末尾使实例变量无效,则请求和响应对象的范围不会扩展到服务方法之外,但他仍然会遇到很大问题。
似是而非。但仍然。如果规范保证保存对这些对象的引用的不确定结果,为什么要这样做呢?
它并不保证任何类型。您可以根据需要保存任意数量的引用,只要您不在服务方法范围之外使用这些引用即可。您只需要以线程安全的方式执行此操作。例如,许多框架在ThreadLocal变量中存储对请求的引用。
我学会了,谢谢。实际上,这变成了一个争论,我不想进入。我批评你和我的。感谢您的所有澄清。
我没那样接受它。我只想捍卫自己的观点,就是这样。
发生的事情是,您的servlet立即变为不可重入,并且在第一次由多个客户端同时调用时肯定会失败。你不能这样做。
这肯定会产生问题,任何实例变量都是共享的,因为servlet是单例,因此将覆盖并发请求和响应对象。
这是一个问题,永远不建议将HttpServletRequest request / HttpServletResponse响应声明为实例变量。实际上Servlet正在实现单线程模型,这意味着只创建了一个servlet实例。每个请求都有一个线程。因此,如果它们有很多请求,则thr必须是多个线程,并且每个线程共享相同的servlet实例,这将导致数据不匹配或数据不一致问题。线程将在相同的实例上工作。
单线程模型!= singleton servlet。单线程模型正是模型(没有人使用因为它效率低下),它保证只有一个线程使用给定的servlet。
不建议使用"单线程实现"。它被弃用了。
-1;这个答案没有提供任何价值。其他人已经说过它的部分错误。