【问题标题】:Java Servlet PoolingJava Servlet 池化
【发布时间】:2009-11-18 12:42:05
【问题描述】:

Tomcat 6 下的 Servlet 101:

谁能给我一个很好的解释,例如最好的方法。在 servlet 启动时创建一个昂贵的 Foo 对象的集合,并将它们存储在我可以在处理每个请求时访问它们的地方?

据我所知,至少有三种方法可以做到这一点,我对区别有点模糊。我不关心集群或算法来驱逐陈旧的条目或类似的东西,只是基础知识。

干杯,谢谢。

【问题讨论】:

  • 目前为止你发现的这三种方法是什么?
  • 您没有提到昂贵的对象是否可以安全地从多个线程中使用。否则,您将有更少的选择。

标签: java servlets pooling


【解决方案1】:

实现一个ServletContextListener,在contextInitialized()期间执行所需的加载任务,并将结果存储在ServletContext#setAttribute()的应用范围内。它将在服务器启动期间被调用,并且应用程序范围也可以在常规 servlet 中访问。

基本示例:

public class Config implements ServletContextListener {
   public void contextInitialized(ServletContextEvent event) {
        List<Foo> foos = fooDAO().list();
        event.getServletContext().setAttribute("foos", foos);
    }
}

以通常的方式将其映射到web.xml

<listener>
    <listener-class>mypackage.Config</listener-class>
</listener>

以下是在常规 servlet 中访问它的方法:

protected void doSomething(request, response) {
    List<Foo> foos = (List<Foo>) getServletContext().getAttribute("foos");
}

以下是在 JSP 中访问它的方法:

<c:forEach items="${foos}" var="foo">
    ${foo.someProperty}<br>
</c:forEach>

也就是说,我真的不明白这与“servlet 池”有什么关系。这个词没有意义。

希望这会有所帮助。

【讨论】:

  • 谢谢,,, contextInitialized 接口方法和 init() 的主要区别是什么?你能澄清更多吗?
【解决方案2】:

您有多种选择:

  • 使用commons-pool,在启动时启动您的对象,然后从池中借用它们。
  • 确保您确实需要对象池。在许多情况下,您可以只创建一个对象并以线程安全的方式访问它。 spring framework 是一个值得一看的好地方。

【讨论】:

    【解决方案3】:

    您正在寻找一个对象池。通常,对象池是使用空闲对象列表构建的,当资源被释放而未达到最大空闲对象数量时,将添加到列表中。

    我不会预先填充池,如果空闲对象池为空,只需分配一个新对象。

    一个显着的性能优势是为最后一个释放的对象保留 1 个引用。对于分配和释放 1 个对象的情况,不必将其添加到空闲对象列表中可以节省很多。如果引用不是null,则将下一个释放的对象添加到列表中,分配时返回最后一个释放的对象和null

    【讨论】:

      【解决方案4】:

      您可以使用servlet context

      servlet 上下文对所有 servlet 实例都是通用的,它的生命周期超出了请求和会话。

      你可以放任何东西,比如:

      public void doGet( HttpServletRequest request, HttpServletResponse response ) {
      
           ServletContext sc = getServletContext();
      
           List expensiveObjectList = ( List ) sc.getAttribute("someName");
           if( expensiveObjectList == null ) {
               expensiveObjectList = someExpensiveInitializationMethod();
               sc.setAttribute( "someName", expensiveObjectList );
           }
      
           // use the list... 
      }
      

      这是一个链接,您可以在这里阅读更多内容about it

      【讨论】:

        猜你喜欢
        • 2015-06-15
        • 2016-05-14
        • 2013-12-08
        • 1970-01-01
        • 1970-01-01
        • 2012-03-02
        • 1970-01-01
        • 1970-01-01
        • 2019-10-21
        相关资源
        最近更新 更多