什么是单例模式
在现实世界中经常会遇到这样的情况,一种类型只有一个实例。比如说一个部门只有一个经理,一个国家只有一个主席等。在面向对象的世界里,如果一个类型只有一个对象实例,那么这个类型就称为单例。实现单例的方法就是单例模式。
定义:确保一个类只有一个实例,并提供一个全局的访问点。
懒汉模式
package com.stone.designpattern.singleton;
public class SingletonLazyModel {
private SingletonLazyModel(){}
private static SingletonLazyModel instance;
/* 线程不安全
* */
public static SingletonLazyModel getInstance() {
if(instance == null){
instance = new SingletonLazyModel();
}
return instance;
}
}
这种实现方法在多线程的环境中会生成多个实例,也就是线程不安全。
只要把getInstance方法标记成synchronized 的就可以了
package com.stone.designpattern.singleton;
public class SingletonLazyThreadSafe {
private SingletonLazyThreadSafe(){}
private static SingletonLazyThreadSafe instance;
/* 线程安全 */
public static synchronized SingletonLazyThreadSafe getInstance() {
if(instance == null){
instance = new SingletonLazyThreadSafe();
}
return instance;
}
}
但是同步方法的话会带来性能的损失,相比非同步方法性能会下降100倍。如果频繁调用同步方法的话,会对应用的性能造成很大的影响。接下来看另外一种方法:
双重校验机制
package com.stone.designpattern.singleton;
public class SingletonLazyModelDCL {
private static volatile SingletonLazyModelDCL instance;
private SingletonLazyModelDCL(){}
public static SingletonLazyModelDCL getInstance(){
if(instance == null){
synchronized (SingletonLazyModelDCL.class){
instance = new SingletonLazyModelDCL();
}
}
return instance;
}
}
这种方式只有在第一次调用getInstance方法时才会同步调用,在保证线程安全的同时大幅提升应用的性能。
饿汉模式
package com.stone.designpattern.singleton;
public class SingletonHungryModel {
private SingletonHungryModel(){}
private static SingletonHungryModel instance = new SingletonHungryModel();
public static SingletonHungryModel getInstance(){
return instance;
}
}