如果我在Tomcat(或任何其他服务器)的单个实例上部署并运行相同应用程序的2个实例。然后将创建一个单独的对象(Singleton类):
所以基本上我想要理解,每个JVM都会创建一个Singleton类的单个对象吗?如果托管在Web服务器(或容器)上的应用程序,这是如何工作的。
答案 0 :(得分:27)
如果您有一个单例类,并且在Tomcat中运行两个使用此类的Web应用程序,则两个webapps将在运行Tomcat的JVM中获得此单例的2个不同实例。
但是如果您的webapp将使用来自JRE或Tomcat共享库的单例,例如Runtime.getRuntime webapps将获得相同的Runtime实例。
这是因为Tomcat为webapps使用了单独的类加载器。当webapp类加载器加载一个类时,它首先尝试在webapp类路径上找到它,如果找不到该类,它会要求父类加载器加载该类。
答案 1 :(得分:20)
单身人士通常只与ClassLoader
绑定。
因此,如果您的.war文件中有.class文件的单例,并且多次部署此Web应用程序,则每个应用程序都有自己的单例。
另一方面,如果您的单例的.class文件位于tomcat
的类路径中,那么您只有一个实例。此.class不属于特定的Web应用程序(它属于tomcat
实例)。
如果两个位置都有单例,则它取决于类加载器层次结构,您可以选择“父优先”或“首先是Web应用程序”。
答案 2 :(得分:4)
可以通过确保始终为单例查询相同的ClassLoader
来创建这样的单例。我在另一个答案中写了extensive explanation。
答案 3 :(得分:1)
<shakey-ground>
据我所知,每个类加载器的单例是唯一的。所以我认为你的问题的答案取决于容器加载Web应用程序的方式。
如果它为每个Web应用程序分配一个类加载器,那么您似乎会得到两个完全独立的单例对象。如果它分配了一个类加载器并且所有Web应用程序都使用它,那么它们共享相同的单一实例。</shakey-ground>
答案 4 :(得分:1)
JVM类比:
JVM就像大宅一样。它包含组合家庭与几个应用程序和库。
ClassLoaders是系列成员,每个系列成员代表一个ClassLoader(作为委托层次结构而不是入侵层次结构)。注意:ClassLoader是类,它可以创建多个实例。
应用程序就像设备一样。例如:洗衣机,冰箱,空气冷却器,Telivision,餐桌,沙发等......
每个图书馆都有自己独立的图书馆。如果没有找到父母的自由中的每一个搜索,那么在他自己的图书馆中搜索。
限制: 如果父亲购买器具,他们的孩子可以使用它,但它的父母和兄弟姐妹不能使用它。 每个应用程序可能使用相同库的不同版本。即如果图书馆包含两本或两本以上版本的相同图书,则会选择该图书可用的图书。
每个家庭号码只能使用一个唯一的设备。
在家里,我们可以使用相同版本的多件装置。因此,JVM允许我们运行相同版本的多个应用程序。
垃圾收集器是Mansion中的一个服务器,它作为守护进程漫游,可以清除任何类型的对象。
静态变量的范围限制为每个ClassLoader一个。