单例模式Singleton,一般有三个步骤:
一、私有化一个静态类变量(这里可以使用 volatile 关键字确保new对象的三条指令顺序不被重排序)
new对象时虚拟机操作步骤:
1.开辟空间(堆) 2.初始化空间 3.空间地址引用赋值给变量名(指针)
这三条指令,计算机可能会在执行的时候重新排序,多线程访问时可能会造成空指针
二、私有化构造方法
三、getInstance方法返回第一部的类变量
懒汉模式
采用双重锁保证线程安全
class lazySingleton {
private volatile static lazySingleton instance; //1.提供静态变量
private lazySingleton() {
} //2.私有化构造方法
public static lazySingleton getInstance() { //3.写getInstance方法
if (null == instance) { //一重判断
synchronized (lazySingleton.class) { //上锁
if (null == instance) { //二重判断
instance = new lazySingleton();
}
}
}
return instance;
}
}
饿汉模式
利用虚拟机JVM进行对象的实例化,保证了实例化的线程安全
只有在真正使用对象时,才会触发对象实例化:比如Main函数进行new、访问静态变量、调用静态方法、反射等(可以使用内部类进行懒加载,确保只有调用getInstance方法才会实例化对象)
class hungrySingleton {
private volatile static hungrySingleton instance = new hungrySingleton(); //私有实例化对象
private hungrySingleton() {
} //私有化构造方法
public static hungrySingleton getInstance() { //getInstance方法
if (instance != null){
throw new RuntimeException("已实例化");
//添加判断和异常抛出避免通过反射获得访问权从而多次实例化对象
}
return instance;
}
}
枚举模式
枚举可以确保只有一次实例化
反序列化
反序列化会破坏掉单例模式