单例设计模式如果一个类只允许创建一个对象(或者实例),那么这个类就是一个单例类,这种设计模式,简称单例模式。
单例模式的两种方法:饿汉单例设计模式、懒汉单例设计模式
饿汉(线程不安全):先创建在使用
懒汉(线程安全):创建的时候才开始创建
singletion = new Singletion() 可以拆解为3步:
1.分配内存
2.初始化对象
3.指向分配对象的地址,若发生重排序双重检查锁:
假设A线程执行了1和3,还没有执行2,B线程来判断NULL,B线程就会直接返回还没初始化的instance了。valatile可以避免重排序。
饿汉的代码实现:
class Singleton{
private static Singleton singleton = new Singleton();
private Singleton(){};
public static Singleton getInstance(){
return null;
}
}
懒汉的实现:
class Singleton01{
private static Singleton01 singleton01;
private Singleton01(){};
public static Singleton01 getInstance(){
if (singleton01==null){
singleton01 = new Singleton01();
}
return singleton01;
}
}
因为上述懒汉模式有漏洞,因为会多次实例化,所以我们用同步锁(synchronized)来解决这个问题
class Singleton02{
private static Singleton02 singleton02;
private Singleton02(){};
// 加锁(synchronized),来防止它被多次实例化
public synchronized static Singleton02 getInstance(){
if (singleton02==null){
singleton02 = new Singleton02();
}
return singleton02;
}
}
在做同步处理时候,同步处理的整个范围是整个方法,但是我们的实例化仅仅发生在第一次,一次发生后,下次判断就不能是空了,就不会进行实例化了。但是每次使用同步锁方法的时候还得实现同步锁的代码块,所以解决方法是缩小同步范围:在第一次判断为空的时候,我们就加锁以便于实例化:双重检查锁
class Singleton03{
private volatile static Singleton03 singleton03;
private Singleton03(){
System.out.println("对象被创建");
};
//使用双重检查锁:
public static Singleton03 getInstance(){
if (singleton03==null){
synchronized (Singleton03.class){
if (singleton03==null){
singleton03 = new Singleton03();
}
}
}
return singleton03;
}
}



