/*
饿汉单例设计模式:(线程安全)
1.私有化构造函数
2.声明本类的引用类型变量,并且使用该变量指向本类对象
3.提供一个公共静态方法获取本类对象
*/
class single{
private static single s=new single();
private single(){};
public static single getSingle(){
return s;
}
}
/*
懒汉单例设计模式:(线程不安全)
1.私有化构造函数
2.声明本类的引用类型变量,但是不创建对象
3.提供一个公共静态方法获取本类对象,获取之前先判断是否创建了本类对象
*/
class single{
private static single s;
private single(){};
public static single getSingle(){
if(s==null){
s=new single();
}
return s;
}
}
/*
静态内部类:
*/
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){};
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
/*
双重校验锁:
初始化一个实例(SomeType st = new SomeType())在java字节码中会有4个步骤,
1,申请内存空间 2,初始化默认值(区别于构造器方法的初始化) 3,执行构造器方法 4,连接引用和实例。
这4个步骤后两个有可能会重排序,1234 1243都有可能,造成未初始化完全的对象发布。volatile可以禁止指令重排序,从而避免这个问题。
由于volatile关键字可能会屏蔽掉虚拟机中的一些必要的代码优化,所以运行效率并不是很高。因此一般建议,没有特别的需要,不要使用。
*/
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){};
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}