具有同步块的Servlet init方法

时间:2013-05-08 09:10:38

标签: java servlets

我有一个问题。在我的应用程序中,我有一个servlet,其初始化代码如下所示。

public class GameInitServlet extends HttpServlet {

private static boolean initialized = false;

 @Override
    public void init() throws ServletException {
        // This is a safeguard against running init() more than once.
        synchronized (GameInitServlet.class) {
            if (initialized) {

                LOG.error("GameInitServlet has already been initialized... Bailing out!");
                return;
            }
            initialized = true;
        }
        //some code here....
    }
}

注意:在web.xml中 上面的servlet在启动时加载为1,因此它会在启动应用程序时初始化。

所以我的问题是为什么我们要同步init方法。毕竟它将由servlet容器处理并且只被调用一次。 我是否可以删除上述同步过程,或者在删除此应用程序后会对应用程序产生一些影响。

3 个答案:

答案 0 :(得分:3)

当Servlet最初加载到Container将创建的单个实例的容器中时,

init()仅执行一次。然后将为每个请求执行doGet()doPost()方法作为单独的执行线程。我没有看到任何同步init()方法或其中的任何代码的点。即使在分布式环境中,每个JVM也可能有一个Servlet实例 。我认为Container足够明智,只能在Servlet的生命周期内调用init()一次,因此不会有任何争用。多个线程来执行init()。根据{{​​3}},

servlet容器在实例化servlet后只调用一次init方法。在servlet可以接收任何请求之前,init方法必须成功完成。

答案 1 :(得分:1)

正如评论所说

// This is a safeguard against running init() more than once.

这只是试图挽救一些永远不会发生的种族条件。

只要webapp存在,任何Servlet,过滤器和监听器都会存在。它们在所有会话中的所有请求中共享。

所以你可以说init()方法在容器中被调用一次。因此不需要同步块。

但是,你是在级别而不是在对象级别进行锁定,原因是什么?您应该检查任何同步的静态调用,可能有一个有效的原因有此块。如果没有,你可以删除它。

您可以看到一些很好的解释here

答案 2 :(得分:0)

总的来说,我同意你的评估。

它似乎没有实现单线程,因此删除“sychronized”不应该受到伤害。

另一方面,它几乎不会导致性能损失,因此移除仅仅是为了“减少”。

相关问题