什么是单例模式?在一个项目中,单例模式确保某一个类只能有一个实例,这个类称为单例类。
怎样确保某个类只能有一个实例,通常调用方法有两种方式:
- 创建类的一个对象,即new出一个对象,用该对象去调用类中方法;
- 使用类名直接调用类中方法,格式“类名.方法名()”
想要类只有一个实例,必不能随意通过new出对象,禁止new对象就只能私有化构造方法,采用“类名.方法名()”这种方式获取方法。通过类名对用方法,此方法是属于类的方法,由于类的加载顺序限定,此方法必须是静态(static)的,且方法里的属性也必须是静态的。
单例核心三要素:
1. 构造方法私有化
2. 提供静态(static)的得到类对象的方法
3. 类属性设为static
单例模式根据对象的创建时间不同,有分为EagerSingleton和LazySingleton。
EagerSingleton方法:
public class EagerSingleton {
/** 静态方法访问静态成员变量*/
private static EagerSingleton instance = new EagerSingleton();
/** 私有构造方法,防止被实例化 */
private EagerSingleton(){
}
/** 提供调用的方法 */
public static EagerSingleton getInstance(){
return instance;
}
}
EagerSingleton方法缺点是该类加载的时候就会直接new 一个静态对象,当系统中单例类较多时,会使得启动速度变慢。
LazySingleton方法:
public class LazySingleton {
//非线程安全
private static LazySingleton instance = null;
private LazySingleton(){
}
public static LazySingleton getInstance1(){
if(instance == null){
instance = new LazySingleton();
}
return instance;
}
}
提供双重锁写法,保证线程安全:
public class DoubleCheckLock {
private volatile static DoubleCheckLock instance = null;
private DoubleCheckLock(){
}
public static DoubleCheckLock getInstance(){
if(instance == null){
synchronized (DoubleCheckLock.class) {
if(instance == null)
instance = new DoubleCheckLock() ;
}
}
return instance;
}
}
“双重检查加锁”机制是当每次执行getInstance方法时先不同步,先检查instance是否存在,如果不存在才进行加锁,这是第一重检查;进入同步块synchronized 方法后,再次检查实例是否存在,如果不存在就创建实例instance,这是第二重检查。DoubleCheckLock 机制使用关键字volatile,被volatile修饰的变量值不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的操作该变量。
参考:
1.https://www.cnblogs.com/java-my-life/archive/2012/03/31/2425631.html