为什么(javax.servlet。)不推荐使用SingleThreadModel?

为什么不推荐使用javax.servlet.SingleThreadModel

javadoc说明了原因。 SingleThreadModel旨在成为低负载并发的简单解决方案,但它甚至没有管理:

请注意,SingleThreadModel不能解决所有线程安全问题。 例如,即使使用SingleThreadModel servlet,仍可以同时在多个线程上通过多个请求访问会话属性和静态变量。 建议开发人员采取其他方法来解决这些问题而不是实现此接口,例如避免使用实例变量或同步访问这些资源的代码块。

如果它无法实现它的设计目标,则不应使用它。

它基本上是一种处理并发的糟糕方式。 取而代之的是从servlet中取出状态,以便多个线程可以同时使用相同的servlet。 将状态保存在servlet实例的“池”中,每个实例都可以从先前的请求中保留状态等,这非常可怕。

是的,不推荐使用SingleThreadModel接口。 不要使用它。 事实上你不需要它,而是使用局部变量而不是对象字段,因为“每个线程都在Java中获取自己的局部变量副本。通过简单地删除对象字段并用局部变量替换它,这个特殊的线程问题是解决。” 参考

来自Java Servlet规范:

使用SingleThreadModel接口可确保一次只有一个线程将在给定的servlet实例的服务方法中执行。 重要的是要注意,此保证仅适用于每个servlet实例,因为容器可以选择池化这些对象。 一次可以访问多个servlet实例的对象(例如HttpSession的实例)可以在任何特定时间到达多个servlet,包括那些实现SingleThreadModel的servlet。
建议开发人员采取其他方法来解决这些问题而不是实现此接口,例如避免使用实例变量或同步访问这些资源的代码块。 在此版本的规范中不推荐使用SingleThreadModel接口。

如果servlet实现了SingleThreadModel接口,则servlet容器可以根据请求加载创建一个或多个servlet实例。 每个实例仅使用其service()方法。 它解决了线程安全问题,但不是所有问题。 比如静态类变量,会话属性仍然不是线程安全的。

鼓励使用此接口开发人员来使用同步访问这些资源的代码块,而不是使用此接口。