参考:Head First Servlets&JSP,第204页,第三个问题:
问:“
实现SingleThreadModel的效果实际上是
与同步服务方法相同。都
可以在没有保护的情况下使Web应用程序瘫痪
会话和上下文状态。”
这是什么意思:“在不保护会话和上下文状态的情况下使Web应用崩溃”?他们是在说实现SingleThreadModel不够线程安全吗?因为即使一次只能在一个servlet上运行一个线程,这也不会阻止其他servlet访问和更改上下文/会话作用域变量吗?如果Servlet实现SingleThreadingModel,那么为什么需要保护会话状态?一次只允许一个线程。我认为,即使您打开一个新的浏览器窗口,该servlet也不允许您发出两个请求。也许他们的意思是,如果一次不使用一个线程的不同Servlet如果不同步,则仍然会破坏上下文/会话状态?
为什么类(静态)变量不是线程安全的?因为所有线程都可以访问和修改(损坏)该值?
对我来说仍然有点模糊。
最佳答案
参考:Head First Servlets&JSP,第204页,第三个问题:
问:“
实现SingleThreadModel的效果实际上是
与同步服务方法相同。都
可以在没有保护的情况下使Web应用程序瘫痪
会话和上下文状态。”
这是什么意思:“在不保护会话和上下文状态的情况下使Web应用崩溃”?他们是在说实现SingleThreadModel不够线程安全吗?因为即使一次只能在一个servlet上运行一个线程,这也不会阻止其他servlet访问和更改上下文/会话范围的变量吗?
这是对的。
如果Servlet实现SingleThreadingModel,那么为什么需要保护会话状态?一次只允许一个线程。我认为,即使您打开一个新的浏览器窗口,该servlet也不允许您发出两个请求。
那是不对的。您可以有另一个选项卡,另一个窗口或其他任何内容。您可能无法同时访问相同的Servlet,因为可能会被阻止,但是您可以访问另一个Servlet,该Servlet也访问相同的Context或Session。并且,根据API,允许同一Servlet的多个实例在不同的线程中服务多个响应(唯一的限制是一个实例不能服务多个线程)。
也许他们的意思是,如果一次不使用一个线程的不同Servlet如果不同步,则仍然会破坏上下文/会话状态?
为什么类(静态)变量不是线程安全的?因为所有线程都可以访问和修改(损坏)该值?
与实例变量相比,静态变量本质上或多或少不是线程安全的。但是您必须了解如何保护值以及如何实现SingleThreadModel。如果SingleThreadModel是通过允许Servlet的多个实例(每个实例都停留在单个Thread上)实现的,则静态变量将在所有实例之间共享,因此它们的线程也可以访问。
无论如何,我认为您永远不要在Servlet类中使用(非最终)静态变量,因为您无法控制Servlet的生命周期。可以根据容器要求创建,销毁和重新创建它。因此,当您下次尝试访问它时,您在静态变量中输入的值可能不存在。而且,永远不要使用SingleThreadModel,因为它效率低下并且没有真正完成其工作,并且已经弃用了很长时间。因此,您绝对不应同时使用它们。