【发布时间】:2011-02-02 20:46:43
【问题描述】:
为什么不推荐使用javax.servlet.SingleThreadModel?
【问题讨论】:
标签: java multithreading servlets
为什么不推荐使用javax.servlet.SingleThreadModel?
【问题讨论】:
标签: java multithreading servlets
这基本上是一种处理并发的糟糕方式。取而代之的是从 servlet 中取出状态,以便多个线程可以同时使用同一个 servlet。将状态保存在 servlet 实例的“池”中,每个实例都可以保留上一个请求等遗留下来的状态,这非常可怕。
【讨论】:
javadoc 说明了原因。 SingleThreadModel 旨在成为低负载并发的简单解决方案,但它甚至没有做到这一点:
请注意,SingleThreadModel 不 解决所有线程安全问题。为了 例如,会话属性和静态 变量仍然可以通过 多个线程上的多个请求 同时,即使当 使用 SingleThreadModel servlet。 建议开发商 采取其他方式解决这些问题 问题而不是实施这个 接口,例如避免使用 实例变量或 同步代码块 访问这些资源。
如果它不能达到它的设计目的,就不应该使用它。
【讨论】:
SingleThreadModel 自 Servlet 2.4 起已被弃用,并在 Servlet 6.0 中被删除。
来自 Java Servlet 规范:
使用 SingleThreadModel 接口可以保证只有一个 一次线程将在给定的 servlet 实例的服务中执行 方法。请务必注意,此保证仅适用于 每个 servlet 实例,因为容器可以选择池化这样的 对象。多个 servlet 实例可以访问的对象 一次,例如 HttpSession 的实例,可能在任何时候都可用 多个 servlet 的特定时间,包括那些实现 单线程模型。
建议开发人员采取其他方式来解决这些问题,而不是实现此接口,例如避免 实例变量的使用或同步块 访问这些资源的代码。 SingleThreadModel 接口是 在此版本的规范中已弃用。
【讨论】:
是的 SingleThreadModel 接口已被弃用。不要使用它。实际上你不需要它,而是使用局部变量而不是对象字段,因为“每个线程在 Java 中都有自己的局部变量副本。只需删除对象字段并将其替换为一个局部变量,这个特殊的线程问题就解决了。” Reference
【讨论】:
如果一个servlet实现SingleThreadModel接口,servlet容器可以根据请求负载创建一个或多个servlet实例。每个实例将只使用它们的service() 方法。它解决了线程安全问题,但不是全部。比如静态类变量,会话属性仍然不是线程安全的。
鼓励开发人员使用同步访问这些资源的代码块,而不是使用此接口。
【讨论】: