跨JVM或Application实例或Tomcat实例的单例

Lea*_*ner 20 java singleton webserver tomcat jvm

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

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

所以基本上我想要理解的是,每个JVM都会创建一个Singleton类的单个对象吗?如果应用程序托管在Web服务器(或容器)上,这是如何工作的.

Evg*_*eev 30

如果您有一个单例类,并且在Tomcat中运行两个使用此类的Web应用程序,则两个webapps将在运行Tomcat的JVM中获得此单例的2个不同实例.

但是,如果您的webapp将使用来自JRE或Tomcat共享库的单例,例如Runtime.getRuntime webapps将获得相同的Runtime实例.

这是因为Tomcat对webapps使用单独的类加载器.当webapp类加载器加载一个类时,它首先尝试在webapp类路径上找到它,如果找不到该类,它会要求父类加载器加载该类.

  • @Evgenniy,这是否意味着在我的单个应用程序中,我可以使用不同的类加载器创建2个单例对象(只是一个想法). (2认同)
  • 不,这要感谢运行在不同类加载器中的不同服务器应用程序的行为就像它们在两个独立的JVM中运行一样 (2认同)

Ber*_*ium 20

单身人士通常ClassLoader只与一个人联系在一起.

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

另一方面,如果你的单例的.class文件在classpath中tomcat,那么你只有一个实例.此.class不属于特定的Web应用程序(它属于tomcat实例).

如果两个位置都有单例,则它取决于类加载器层次结构,您可以在"父优先"或"首先是Web应用程序"之间进行选择.


Raf*_*ter 5

通过确保您始终ClassLoader为单例查询相同的内容,可以创建这样的单例。我在另一个答案中写了一个广泛的解释


Pre*_*raj 5

  • Tomcat 为每个 Web 应用程序创建新的类加载器。
  • 因此,如果您的 Singleton 类存储在 war 文件中,则同一个 war 文件将在 Tomcat 容器中拥有两个实例,即它为每个 war 文件创建两个单独的 Singleton 类。
  • 如果 Singleton 类位于 Tomcat 的共享库路径中,则 Tomcat 只会为这两个应用程序创建一个 Singleton 实例。

JVM 类比:

JVM 就像一座大宅子。它包含具有多种电器和图书馆的组合系列。

类加载器是家族成员,每个家族成员代表一个类加载器(作为委托层次结构而不是继承层次结构)。注意:ClassLoader是类,它可以创建多个实例。

应用程序就像电器。例如:洗衣机、冰箱、冷气机、电视、餐桌、沙发等...

每个图书馆都有自己的图书馆。每个人都在父母的图书馆中搜索,如果没有找到,则在自己的图书馆中搜索。

限制:如果父亲购买了一个电器,他们的孩子可以使用它,但他的父母和兄弟姐妹不能使用它。每个应用程序可能使用相同库的不同版本。即,如果图书馆包含同一书籍的两个或多个版本,则它会首先选择可用的书籍。

每个家庭号码只能使用一台唯一的设备。

在家里,我们可以使用多个相同版本的设备。因此,JVM 允许我们运行多个相同版本的应用程序。

垃圾收集器是Mansion中的一个仆人,他作为守护进程漫游,可以清除任何类型的物体。

静态变量的范围仅限于每个类加载器一个。