【问题标题】:When does the instance created by the server die?服务器创建的实例什么时候死掉?
【发布时间】:2012-02-22 10:46:12
【问题描述】:

以下程序:

public class SimpleCounter extends HttpServlet {

    int counter=0;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/plain");
        PrintWriter writer = response.getWriter();
        counter++;
        writer.println("accessed " + counter + " times" );
    }
}

每次我访问这个 servlet 的 url 时都会打印 counter 的增量值。我读到服务器创建了这个 servlet 的一个实例,每当有这个 servlet 的请求时,一个新线程就会将此请求映射到服务器创建的特殊实例。

服务器创建的实例(请求映射到哪个线程)什么时候死掉?新请求创建的线程何时死亡?

【问题讨论】:

  • 这是否与特定容器有关?有些应用程序(例如 Google App Engine)会积极回收一段时间内未收到请求的应用程序。
  • @Mike Samuel 实际上不是。但可以包含在答案/讨论中

标签: java multithreading jakarta-ee servlets persistence


【解决方案1】:

servlet 实例在您的 webapp 启动时创建,或者在第一次需要时创建(如果设置了lazy-init)。当你的 webapp 停止时,当它被 GCed 时,它会被处理掉。在正常的生产环境中,我敢说这从未真正发生过(不包括部署新版本)。

大多数(如果不是全部)servlet 容器都使用线程池。这意味着他们重用线程来处理请求。所以这些线程永远不会死;当他们完成执行请求时,他们返回到池中。

当然,当你关闭服务器时它们确实会死掉:)

从您的应用程序的角度来看,您确实应该尝试使您的 servlet 无状态,并且您可以放心地认为每个请求都在其自己的专用线程中执行。

【讨论】:

  • “你真的应该尝试让你的 servlet 无状态”你能解释一下吗?
  • 意味着您不应该在其中保留任何应用程序状态。这样您就不必关心它何时被创建或销毁。理想情况下,您甚至不应该关心实例化了多少(这在集群环境中很有用)。
  • @SuhailGupta,简而言之,不要在 Servlet 中使用任何静态变量。
  • @Joeri Hendrickx 如果实例在应用关闭时被销毁,那么可能有许多实例处于活动状态,其中一些可能保持“空闲”状态。如果发生这种情况,会不会造成任何负担?
  • @SuhailGupta 在正常的现实环境中,应用程序仅在您停止服务器时才会停止。那么你真的不在乎。您永远不会只是为了好玩而在生产服务器上部署/取消部署应用程序。在开发期间这可能是一个问题,但通常 GC 会为您清理实例。解决此问题的唯一方法是创建内存泄漏(将对您的 servlet 的引用放入容器中),然后重新部署您的应用程序。
猜你喜欢
  • 2011-10-25
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 2018-03-02
  • 2014-09-14
  • 1970-01-01
  • 2010-11-08
相关资源
最近更新 更多