设计模式之单例模式(Singleton Pattern)
-
单例模式的定义
Ensure a class has only one instance, and provide a global point of access to it。确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个唯一实例。 -
单例模式的通用类图
-
单例模式通用代码
/**
* 单例模式通用代码
*
* @author cm_wang
*
*/
public class SingletonPattern {
private static final SingletonPattern singletonPattern = new SingletonPattern();
// 私有的构造方法,为了限制产生多个对象
private SingletonPattern() {
}
/**
* 通过这个方法获得对象唯一实例
*
* @return
*/
public static SingletonPattern getSingleton() {
return singletonPattern;
}
}
-
正如上面的代码所述一样,单例模式有两个要素要记得
- 私有的构造方法。为了防止系统中出现多个实例,保证该实例的唯一性。
- 以自己实例为返回值的静态的公有的方法。外部会通过这个方法来获取该对象的唯一实例。
-
单例模式会根据实例化对象时机的不同分为两种:一种是
饿汉式单例
,一种是懒汉式单例
。饿汉式单例和懒汉式单例的区别是:饿汉式单例在单例类被加载时候,就实例化一个对象交给自己的引用;而懒汉式单例在调用取得实例方法的时候才会实例化对象
。 -
饿汉式单例代码,正如
单例模式通用代码
一样,这里略。 -
懒汉式单例代码
/**
* 懒汉式单例
*
* @author cm_wang
*
*/
public class SingletonPattern {
private static SingletonPattern singletonPattern;
private SingletonPattern(){}
public static synchronized SingletonPattern getInstance(){
if(singletonPattern==null){
singletonPattern = new SingletonPattern();
}
return singletonPattern;
}
}
细心的小伙伴已经发现getInstance()
加了synchronized
关键字。是因为在多线程的环境下,单例模式会出现线程不安全
的问题,这个时候就需要考虑线程同步。假设线程A执行到singletonPattern = new SingletonPattern();
,但是此时没有获取到对象(毕竟对象的实例化是需要实现的),这个时候线程B也在执行,执行到if(singletonPattern==null)
,线程B就会判断为true
,继续运行下去,这样子就会导致线程A和线程B一下自创建了两个对象,就违背了单例模式的思想,内存中就会存在两个实例。