创建静态引用与单例

时间:2011-12-02 16:45:57

标签: java mongodb singleton

我正在使用mongodb的java驱动程序,文档说:

  

“你应该创建一个Mongo实例,并且可以在每个请求中使用它。”

使用单个实例听起来像单身。

在其他地方,对于不同的库,我已经阅读了说明,我应该创建一个静态引用,因为它是线程安全的。

有人可以解释单例和创建静态引用之间的区别吗?

因此,我需要静态或通过单例实例化的实际代码是:

Mongo m = new Mongo( "localhost" , 27017 );

有人可以解释这两种方法和潜在的差异吗?

5 个答案:

答案 0 :(得分:4)

在Java中,您通常使用静态变量来实现Singleton模式。

http://java.sun.com/developer/technicalArticles/Programming/singletons/

答案 1 :(得分:3)

您有3个问题:单例,静态引用和线程安全。

如果只能创建一个类的实例,那么你有一个单例。这很有用,因为如果有两个Mongo运行实例,事情就会搞砸了。但是,您无法在代码中为Mongo实现单例设计模式:您可以在任何地方调用new Mongo()并根据需要创建任意数量的实例。你必须小心你不要这样做,但它不应该很难。

要实现单例,类设计者经常会使用静态引用,如下所示:

public class MyClass {
  private static final MyClass SINGLETON = new MyClass();

  private MyClass() {...}   // !!private, not accessible

  public MyClass getSingleton() { return SINGLETON; }
}

并且您将只有一个MyClass个实例,因为构造函数是私有的,获取实例的唯一方法是通过MyClass.getSingleton()。显然,Mongo设计师必须设计Mongo类;没有什么可以让它成为一个单身人士。

就线程安全而言,我并不完全看到与单例的链接。必须使单例类成为线程安全的:如果许多线程发生更改并读取单例的状态,则需要进行适当的同步以确保所有线程都看到相同的值。我不知道Mongo,但我敢打赌它是一个线程安全的类。

答案 2 :(得分:2)

Singleton是一个设计模式,您可以在其余代码中共享一个对象实例。静态变量是Java 语言功能

为了实现Singleton,通常使用静态变量。

答案 3 :(得分:0)

如果您只想将此对象的单个实例传递给需要使用此单个实例的其他对象和方法,请在对象上使用Singleton模式。如果您只想静态使用对象的类(即作为静态引用),请使用静态引用。

答案 4 :(得分:0)

如果只有一个类正在使用您的单例对象,则创建的对象数量没有明显差异。

假设你需要一个使用Singleton方法的classASing对象

ClassASing {
     private static ClassASing obj = new ClassASing();
     private ClassAsing(){...}
     public static ClassASing getNewObject(){
          return obj;
     }
}

使用Singleton方法

ClassB{
    private ClassASing singObj = ClassASing.getNewObject();
}
  • 无论ClassB创建了多少个实例,所有这些实例都将使用ClassASing相同的对象

使用静态参考

ClassB{
    private static ClassA sObj = new ClassA();
}

*无论ClassB创建了多少个实例,所有实例都将使用指向同一对象的相同引用。

这两个案例中没有太大区别。

现在,如果你考虑另外一个你需要在你的两个班级中提出反对的仙女座。

单身方法

ClassB1{
            private ClassASing singObj1 = ClassASing.getNewObject();
        }

ClassB2{
            private ClassASing singObj2 = ClassASing.getNewObject();
        }
  • 无论ClassB1创建了多少个实例,所有这些实例都将使用ClassASing的相同对象
  • 无论ClassB2创建了多少个实例,所有它们都将使用ClassBing已经使用的ClassASing的同一对象,因此只有一个ClassASing对象

静态参考方法

ClassB1{
    private static ClassA sObj1 = new ClassA();
}

ClassB2{
    private static ClassA sObj2 = new ClassA();
}
  • 无论ClassB1创建了多少个实例,所有这些实例都将使用相同的引用sobj1指向同一个对象
  • 无论ClassB2创建了多少个实例,它们都会使用指向同一个对象的相同引用sobj2,但是这个对象与ClassB1中创建的对象不同,所以现在你有两个ClassA对象。