单例模式--Head First设计模式【笔记】
红与黑关于小小单件的问答
如何创建一个对象? new MyObject();万一另一个对象想创建MyObject会怎么样?可以再次new MyObject吗? 是的,当然可以
所以,一旦有一个类,我们是否都能多次地实例化它? 如果是公开的类,就可以
如果不是的话,会怎么样? 如果不是公开类,只有同一个包内的类可以实例化它,
但是仍可以实例化它多次。嗯!有意思!你知道可以这么做吗? 我没想过。但是,这是合法的定义,有一定道理 public MyClass { private MyClass(){} }怎么说呢? 我认为含有私有的构造器的类不能被实例化
有可以使用私有的构造器的对象吗? 嗯,我想MyClass内的代码是唯一能调用此构造器的代码,
但是这又不太合乎常理。为什么? 因为必须有MyClass类的实例才能调用MyClass构造器,但是因为
没有其他类能够实例化MyClass,所以我们得不到这样的实例。
这是“鸡生蛋,蛋生鸡“的问题。我可以在MyClass类型的对象上使用
MyClass构造器,但是在这之前,必须有一个MyClass实例。
在产生MyClass实例之前,又必须在MyClass实例内才能调用私有的
构造器。。。嘿! 我有个想法。你认为这样如何? MyClass有一个静态方法。我们可以这样调用这个方法: public MyClass MyClass.getInstance(); { public static MyClass getInstance(){} }为何调用的时候用MyClass的类名,而不是用对象名? 因为getInstance()是一个静态方法,换句话说,是一个”类“方法。
引用一个静态方法,你需要使用类名。有意思。假如把这些合在一起”是否“就可以初始化一个MyClass? 当然可以 public MyClass { private MyClass(){} public static MyClass getInstance() { return new MyClass(); } }好了,你能想出第二种实例化对象的方式吗? MyClass.getInstance();
你能够完成代码使MyClass只有一个实例被产生吗? 嗯,大概可以吧。。。
//黑用一个黑夜整出来的单例模式 public class Singleton { private static Singleton uniqueInstance;//用一个静态变量来记录Singleton类的唯一实例 private Singleton(){} public static singleton getIntance() { if(null==uniqueInstance)//如果我们不需要这个实例,就永远不会产生,这就是”延迟实例化“ { uniqueIntance=new Singleton(); } return uniqueIntance; } }这样就真的能保证一个类只有一个实例,并提供一个全局访问点?在多线程中如果有两个线程都要执行这段代码呢?那又会怎么样?
怎么办?怎么办!怎么办?怎么办?!!!!!!!!!!!!!!!!!!!!!!!
不要急,天塌下来有高个子顶着。前人早就想好了解决方法。随我来一一了解它们吧。
//方法一:饥汉模式 public class Singleton { //使用readonly关键用于指定该常量是类别级的,它的初始化交由静态构造函数实现,并可以在运行时编译。 private static readonly Singleton uniqueInstance=new Singleton ();private Singleton() { } public static Singleton getInstance() { if (null == uniqueInstance) { uniqueInstance = new Singleton(); } return uniqueInstance; } }
//方法二:使用了双重锁方式较好地解决了多线程下的单例模式实现
public class Singleton { private static Singleton uniqueInstance; private static object _lock = new object(); private Singleton() { } public static Singleton getInstance() { if (null == uniqueInstance)//确认要实例化后再进行加锁,降低加锁的性能消耗。 { lock (_lock) { if (null == uniqueInstance) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } }比较下这两种方法,你感觉哪种方法更好?