我在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;
}
}
非常感谢帮助:) 感谢
答案 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
无法创建两次。