跨 JVM 或应用程序实例或 Tomcat 实例的单例

2022-09-01 19:52:11

如果我在Tomcat(或任何其他服务器的单个实例)上部署并运行同一应用程序的2个实例。然后创建一个单例类的单个对象:

  1. 跨 Tomcat 的单个实例(但对于同一应用程序的 2 个实例很常见)或
  2. 跨应用程序实例(对于 2 个应用程序实例不同)

所以从本质上讲,我想了解的是,是否总是每个JVM创建Singleton类的单个对象?如果应用程序托管在Web服务器(或容器)上,这是如何工作的。


答案 1

如果你有一个单例类,并且你运行两个在 Tomcat 中使用此类的 web 应用程序,则这两个 web 应用都将在运行 Tomcat 的 JVM 中获得此单例的 2 个不同实例。

但是,如果您的web应用程序将使用来自JRE或Tomcat共享库的单例,例如 Runtime.getRuntime webapps将获得相同的运行时实例。

这是因为 Tomcat 对 Web 应用使用单独的类装入器。当 webapp 类装入器装入一个类时,它首先尝试在 webapp 类路径上找到它,如果未找到该类,它会要求父类装入器装入该类。


答案 2

单例通常绑定到仅 。ClassLoader

因此,如果 .war 文件中有一个基于 .class 文件的单例,并且多次部署此 Web 应用程序,则每个应用程序都会获得自己的单例。

另一方面,如果单例的 .class 文件位于 的类路径中,则只有一个实例。此.class不属于特定的 Web 应用程序(它属于实例)。tomcattomcat

如果两个位置都有单例,则取决于类装入器层次结构,并且您可以在“父级优先”或“Web 应用程序优先”之间进行选择。


推荐