单例模式的定义
一个类创建的对象都是同一个对象。在运行环境中,通过这个类取得的对象都是同一个。
单例模式的好处
1.节约资源,一个类只能创建一个对象,在运行环境中,所有根据这个类创建的对象都是同一个。
2.可以避免频繁销毁和创建,提高性能。
3.提供一个全局的访问点。
单例模式的主要注意点
创建单例模式首先这个类得有一个私有的构造方法,还有一个私有的静态属性,这个属性的类型就是这个类,并有一个静态的public方法,通过这个静态方法将对象返回。
单例模式结构图
单例模式代码:
单例模式分为懒汉模式和饥汉模式,其中懒汉模式是只要在用到这个对象的时候才会去创建这个对象,这样做的好处就是在不用的时候节省空间;饥汉模式是将这个类加载到jvm中的时候就会去创建这个对象,这样做的好处就是线程安全。
饥汉模式
/**
* 讥汉单例模式
*/
class HungerSingleModle{
private static HungerSingleModle hungerSingleModle= new HungerSingleModle();
private HungerSingleModle(){};
public static HungerSingleModle getHungerSingleModle(){
return hungerSingleModle;
}
}
懒汉模式,双重检查,避免在多线程的情况下破坏了单例的特性
/**
* 懒汉单例模式
*/
class LayzSingleModle{
private static volatile LayzSingleModle layzSingleModle;
private LayzSingleModle(){};
public static LayzSingleModle getLayzSingleModle(){
if(layzSingleModle==null){
synchronized (LayzSingleModle.class){
if(layzSingleModle==null){
layzSingleModle = new LayzSingleModle();
}
}
}
return layzSingleModle;
}
}
其中要注意在申明属性的时候要加上volatitle,这是为了避免指令重排,如果不加入volatitle的话,在多线程的情况下,获取到的LayzSingleModle对象有可能不是一个完整的对象,因为new一个对象是分为好几步的:
第一步:分配内存空间;
第二步:初始化对象;
第三步:将对象赋值给layzSingleModle属性。
第二步和第三步是可以顺序交换的,要是第三步先执行,然后又来一个创建单例的请求,发现layzSingleModle不为空了,直接返回,但是layzSingleModle获取到的是一个没有初始化的对象,所以就会有问题。