如何在Java中创建同步的Singleton设计模式?

时间:2014-06-05 07:35:10

标签: java

我在Java中经历过单例设计模式,如下所述。我无法理解公共静态getter 访问者方法中的同步关键字如何阻止创建多个对象? 如果它从两个不同的类中被调用两次同步应该使它们的调用同步,即一个接一个。它如何仅管理一个对象创建? 如果我对修饰语的假设是正确的,请详细解释并检查评论

class MySingleton
{
private static MySingleton singletonObj; //as it is private it cannot be referenced outside of this class
                                         //and as it is static all the instances of this class share the same copy of this refrence variable
private MySingleton()
{
    System.out.println("Welcome to a singleton design pattern");
    System.out.println("Objects cannot be instantiated outside of this class"); 
}

public static synchronized MySingleton getASingletonObject()
{
    if(singletonObj==null)
    {
        singletonObj=new MySingleton();
    }
    return singletonObj;
}


}

非常感谢帮助:) 感谢

5 个答案:

答案 0 :(得分:3)

你的问题是关于它的工作方式:你有一个实例不是因为同步,而是因为它存储在一个静态变量中,并且只有一次实例(具有延迟创建 - 由if检查)。

synchronized确保只有一个Thread会实例化对象,并避免许多线程可能产生重复的错误。

以下是实现它的另一种方法,我发现它更简单,效率更高:

public class Singleton
  private static final Singleton instance=new Singleton();
  private Singleton(){
  }
  public static Singleton getInstance(){
    return instance;
  }
}

注意:使用这种实现的唯一条件是你的构造函数(new)不应抛出任何异常,并且应该只包含简单的代码,如变量初始化。

答案 1 :(得分:2)

Singleton类的目的是它最多只有一个实例,因此所有线程都访问同一个对象。 假设有'n'个线程试图访问 getASingletonObject 方法。

案例I:如果我们不同步 getASingletonObject 方法,可能会发生以下情况:

1)Thread1进入 getASingletonObject ()

2)Thread2进入 getASingletonObject ()

3)Thread1将singletonObj == null计算为true

4)Thread2将singletonObj == null计算为true

5)Thread1分配singletonObj并返回

6)Thread2 * re *指定singletonObj = new Singleton()并返回。

现在线程都有Singleton类的不同实例,这是该模式应该阻止的。

同步可防止两个线程同时访问同一个代码块。因此,在实例化单例类时,在多线程环境中需要同步。

现在假设多线程将尝试访问Singletons方法,同时也可能需要同步这些方法。特别是如果他们改变数据而不是只读它,这是真的。

答案 2 :(得分:1)

你没有正确实现Singleton模式看我的实现。

     class MySingleton
     {

     private MySingleton instance; //You dont need that you instance be static, inside your class you have all the access of the Instance once you call getInstance()

     public static MySingleton getIntsance(){
              return instance;
     }


     private MySingleton() 
     {   
         System.out.println("Welcome to a singleton design pattern");
         System.out.println("Objects cannot be instantiated outside of this class"); 
     }

     public static synchronized MySingleton getASingletonObject()
     {
         if(instance==null)
         {
             instance=new MySingleton();
         }
         return instance;
     }

 }

//关于同步,你必须要理解,就像一个锁,每次一个线程进入内部时他都在关闭方法,所以没有其他人可以在里面,然后在线程进入时不可能line instance = new MySingleton();但是没有为VM执行另一个线程将在if(instance == null)中询问VM并返回true。 一旦第一个步骤超出方法,锁就会打开,然后其他线程就可以进入。然后他们就会看到实例已经创建了。

答案 3 :(得分:1)

synchronized 关键字保护单线程成员变量(在本例中为singletonObj)不受多线程访问的影响。这确保即使多个线程试图创建对象,仍然只使用一个。

查看此文章:http://www.javaworld.com/article/2073352/core-java/simply-singleton.html了解更多说明。

答案 4 :(得分:0)

维基百科说:

  

在软件工程中,单例模式是一种设计模式   这会将类的实例化限制为一个对象。

因此,您只创建一次singletonObj,因为当您致电getASingletonObject()时,您检查的是singletonObj == null,如果它为空,那么您创建一个新对象,如果它& #39; s not null你得到' singletonObj'之前创建。

public static synchronized让您确信此对象已创建一次,因为static表示已为类创建了singletonObj一次,但没有为对象的具体实例创建。并且synchronized提供了对getASingletonObject()的并发访问权限,并且它让您相信当不同的线程同时调用您的方法时,对象singletonObj无法创建两次。