【问题标题】:Servlet Instance in the container容器中的 Servlet 实例
【发布时间】:2011-08-02 11:23:19
【问题描述】:

我知道只有一个 servlet 实例(一个实例用于一个 servlet 基础)将在 Web 容器中可用。是否可以在 Web 容器中创建一个实例池?像数据库连接?如果我创建一个 servlet 实例池,那么我如何将其作为线程安全的? (但我研究过每个 servlet 只能创建一个 servlet 实例)。

【问题讨论】:

    标签: java servlets


    【解决方案1】:

    我知道这是一个面试问题。我会这样回答:

    您可以让 servlet 实现 SingleThreadModel 以使容器创建一个包含同一 servlet 类的多个实例的池。最大池大小取决于所使用的容器,例如在 Tomcat 上,这是 20。但是,一个很大的但是,这个接口从 Servlet 2.4 开始就被弃用了!我们实际上应该以线程安全的方式编写 servlet,而不是将请求和/或会话范围的数据分配为 servlet 的实例变量。这样就可以安全地跨多个线程使用单个 servlet 实例(阅读:跨多个 HTTP 请求)。

    另见:

    【讨论】:

      【解决方案2】:

      问题是,你为什么要这样做?

      Servlet 容器为每个 servlet 声明实例化单个实例。这意味着,您可以拥有多个 servlet 实例,但您需要声明 servlet 的次数与您想要/需要的实例数一样多。这也带来了如何调用 servlet 的问题……它们需要映射到不同的路径。

      您可以这样做的另一种方法是创建一个处理程序池,您的单个 servlet 可以调用这些处理程序。

      关于如何使它们成为线程安全的:这取决于你想在这些处理程序中做什么。一般情况下很难告诉你。

      如果您询问线程安全池,您可以使用 Apache Commons Pool 库或 Java 中的一些 BlockingQueue(例如 LinkedBlockingQueue):队列可能包含您的处理程序。 Servlet 将take() 第一个处理程序,使用它,并在完成后将put() 返回。 (当然这只是一个例子,实现池的方法有很多)。

      但是...确保您真的需要这样的设计,也许您的要求可以通过更简单的方式来满足? (如果您的目标是限制同时处理的并发请求的数量,也许只限制容器中 HTTP 工作线程的数量就足够了?或者如果这还不够,您可以使用限制过滤器?)

      【讨论】:

      • 这是我面试时遇到的场景!
      【解决方案3】:

      定义 servlet 池没有意义,因为 Servlet 本身不是线程。 Web 容器(例如 Tomcat)维护一个调用 Servlet 实例的线程池。因此,如果您想增加吞吐量(并发用户数),您必须增加 Web 容器的池大小。

      【讨论】:

      • 您可以拥有任何对象的池,而不仅仅是线程。有时它有意义,有时它没有。
      • @Peter Štibraný 无论如何,当我需要一些 servlet 类的实例池时,我找不到原因。
      • @Alexandr,是的,这对 servlet 没有意义。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多