Singleton对象和Java servlet

时间:2012-07-06 08:54:35

标签: java servlets

当我从一个servlet访问一个单独的Java对象时,该对象只是给出servlet线程的“单个”或“一个实例”,或者是整个服务器操作系统上的JVM(如Linux)的单个对象?

我的意思是当客户端连接到servlet / service时,singleton对象对于为每个客户端创建的每个线程是唯一的,还是在机器中安装的整个JVM中是唯一的?

6 个答案:

答案 0 :(得分:3)

我会说这取决于如何实现单例,但是对于给定应用程序的所有请求都在同一个VM中执行,因此它应该是所有请求的一个实例。

编辑:这是假设一个类似于:

的直接Singleton实现
public class MySingleton {
    private static MySingleton _instance;

    // for sake of simplicity, I've left out handling of 
    // synchronization/multi-threading issues...
    public static MySingleton getInstance() {
        if (_instance == null) _instance = new MySingleton();
        return _instance;
    }
}

答案 1 :(得分:3)

我认为该对象对于每个用户都是唯一的,而不是整个JVM。唯一持久性信息是您放入用户会话的信息。

我不确定,但我认为您可以使用ClassLoader class在整个Application Server中创建一个类的实例,但我不知道它是如何完成的。

<强>更新

取自Java文章"When is a Singleton not a Singleton?"

由不同类加载器同时加载的多个单身人士 当两个类加载器加载一个类时,实际上有两个类的副本,每个类都可以拥有自己的Singleton实例。这在某些servlet引擎(例如iPlanet)中运行的servlet中尤为重要,其中每个servlet默认使用自己的类加载器。实际上,访问联合Singleton的两个不同的servlet将获得两个不同的对象。

多个类加载器比您想象的更常见。当浏览器从网络加载类以供applet使用时,它们为每个服务器地址使用单独的类加载器。类似地,Jini和RMI系统可以为它们下载类文件的不同代码库使用单独的类加载器。如果您自己的系统使用自定义类加载器,则可能会出现所有相同的问题。

如果由不同的类加载器加载,则两个具有相同名称,甚至相同包名称的类被视为不同 - 即使实际上它们是逐字节的同一个类。不同的类加载器表示区分类的不同名称空间(即使类的名称相同),因此两个MySingleton类实际上是不同的。 (请参阅参考资料中的“类加载器作为命名空间机制”。)由于两个Singleton对象属于同一个名称的两个类,因此乍一看它会出现两个同一类的Singleton对象。

答案 2 :(得分:1)

是的,Singleton。但单身人士的范围取决于班级所在的位置。

如果它位于应用程序内部,则该应用程序是单例。如果在另一个应用程序中存在相同的类,则为该应用程序创建另一个对象,并且该应用程序是单例。

如果它位于应用程序之外且位于服务器内,则它是VM的单例。

答案 3 :(得分:1)

据此

https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

每个Web应用程序都有其自己的类加载器,因此单例对于一个应用程序来说是唯一的,而对另一个应用程序则不可见

答案 4 :(得分:0)

当您创建Singleton实例时,所有请求实例将共享它使用的当前类加载器的相同实例。

答案 5 :(得分:0)

由于所有Servlets都在运行于单个JVM的网络服务器上运行,因此所有servlet只有一个Singelton对象。