【问题标题】:Servlet specification for singleton servlet object单例 servlet 对象的 Servlet 规范
【发布时间】:2016-04-03 07:45:54
【问题描述】:

对于未实现 SingleThreadModel 接口的 servlet,如果 service 方法已经用 synchronized 关键字定义,servlet 容器不能使用实例池方法(摘自 Java™ Servlet Specification Version 2.5)

所以,它不是 SingleThreadModel,而是规范说实例池方法?通常,如果我们不为 SingleThreadModel 描述 servlet,则只会创建一个实例。我很困惑。

【问题讨论】:

    标签: java servlets jakarta-ee servlet-3.0 java-ee-5


    【解决方案1】:

    您需要阅读 servlet 规范中的全部§2.3.3.1 Multithreading Issues(至少从 Servlet 2.2 开始就已经存在,并且可能更早)以获得这句话的完整上下文.

    容器可以选择创建一个已实现javax.servlet.SingleThreadModel 的servlet 实例池,以提高并发性。然后,每个处理指向该 servlet 的请求的线程都可以执行它自己的 servlet 实例(可能从池中获取),而不是阻塞直到更早的请求完成。

    如果开发者只是选择synchronizeservice或相关方法,容器将不会使用这种机制。

    明确回答您的问题:

    实例池将永远用于未实现 SingleThreadModel 的 servlet。因此,这些类型的 servlet 将始终是单例的。

    这一切都没有实际意义,因为 SingleThreadModel 自 Servlet 2.4 以来已被弃用。

    【讨论】:

    • 请阅读我对规范 2.5 的引用。仔细阅读。 “对于未实现 SingleThreadModel 接口的 servlet”和“如果服务方法已使用 synchronized 关键字定义,则 servlet 容器不能使用实例池方法”。这意味着否则 Servlet 容器在后台将池用于单个实例或多个实例。
    • 我阅读了原始文件。只有SingleThreadModel servlet 将(可能)被池化。
    • 2.3.3.1 多线程问题 // 对于没有实现 SingleThreadModel 接口的 servlet,如果已经定义了服务方法(或分派到 HttpServlet 抽象类的服务方法的 doGet 或 doPost 等方法)使用 synchronized 关键字,servlet 容器不能使用实例池的方式,而必须通过它来序列化请求。
    【解决方案2】:

    你引用的那句话不是很清楚,但在我的解释中它想说的是:

    如果 Servlet 没有实现 SingleThreadModel 但有一个同步的 service 方法(或同步的 HttpServlet#doGet 等方法),那么 servlet 容器将为 servlet 使用实例池.
    请求将简单地通过线程同步进行序列化,并发请求的性能会很差。

    【讨论】:

    • 为什么 serlet 容器只为一个实例使用实例池?
    • @Erdal76t 正如我在回答中所说,我认为对于所描述的情况,容器确实使用实例池。
    • 不,你没有误会我的意思。我再问一次。如果 Servlet 没有实现 SingleThreadModel 并且没有同步服务方法,则 Servlet 容器使用实例池。但是为什么 serlet 容器只对一个实例使用实例池呢?
    • @Erdal76t 我在引用中没有看到任何暗示池用于此类 servlet。
    • 我的意思是 servlet 容器总是对单例 servlet 实例使用“池化方法”,除非未定义同步服务方法或实现 SingleThreadModel。也许它发生在幕后。
    猜你喜欢
    • 2011-01-22
    • 2016-12-01
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 2010-11-14
    • 1970-01-01
    相关资源
    最近更新 更多