单例设计模式(饿汉式VS懒汉式)

什么是单例模式 单例(单个的实例) 1.所谓单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法 2.单例设计模式有两种方式:饿汉式 与 懒汉式

饿汉式: 饿汉式听名字就知道它就像一个饿死鬼一样,有饭就赶紧吃,有饭就抢着吃。 所以,在程序启动或单例模式类被加载的时候,单例模式实例就已经被创建。

创建步骤: 1)构造器私有化 —>防止直接new对象 2)类的内部创建对象 3)向外暴露一个静态的公共方法 (getInstance)

//饿汉式
public class SingletonTest {
          
   
    //私有化类的构造器,让外部无法调用
    private SingletonTest(){
          
   
    }
    //类的内部创建类的对象,并且此对象必须声明静态
    private static SingletonTest instance= new SingletonTest();
    //提供公共的静态的方法,返回类的对象
    public static SingletonTest getInstance(){
          
   
        return instance;
    }
}

懒汉式: 懒汉式顾名思义就像一个懒惰的大汉,能不干活就不干活。所以它直到第一次去使用的时候,才会创建实例对象。

实现步骤: 1.仍然构造器私有化 2.定义一个 static 静态属性对象 3.提供一个 public 的 static 方法,可以返回一个对象 4.懒汉式,只有当用户使用 getInstance 时,才返回对象, 后面再次调用时,会返回上次创建的对象

线程不安全模式

class Singleton{
          
   
	//私有化类的构造器
	private Singleton(){
          
   
	}
	//声明当前类的对象,并且是static,但是没有赋值
	private static Singleton instance = null;
	//声明为public、static的方法用来返回类的实例
	//如果发现当且instance为null,给instance创建一个实例。
	public static Singleton getInstance(){
          
   
		if(instance == null){
          
   
			instance = new Singleton();
		}
		return instance;
	}
}

线程安全模式:

class Singleton{
          
   
	//私有化类的构造器
	private Singleton(){
          
   
	}
	//声明当前类的对象,并且是static,但是没有赋值
	//此处添加volatile是为了防止指令重排序
	private static volatile Singleton instance = null;
	//声明为public、static的方法用来返回类的实例
	//如果发现当且instance为null,给instance创建一个实例。
	public static Singleton getInstance(){
          
   
		if(instance == null){
          
   
			synchronized(Singleton.class){
          
   
				if(instance == null){
          
   
					//这并不是一个原子操作
					//1.给instance分配内存空间
					//2.调用Singleton构造函数初始化
					//3.将instance对象指向分配的内存空间,此时instance不为null
					//使用volatile修饰instance就是防止这1-2-3步被指令重排,保证其顺序执行
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

简简单单的总结一下吧 1.二者最主要的区别在于创建对象时机不同: 1)饿汉式是在类加载就创建了对象 2)懒汉式是在使用时在会创建对象 2.饿汉式不存在线程安全问题,懒汉式存在线程安全问题 3.饿汉式存在浪费资源的可能,因为它是在类加载的时候就创建了对象吗, 如果我们不使用它,那不就浪费了。 懒汉式是在使用的时候才会创建,所以就不存在这个问题啦。

补充:在我们javaSE标准类中,java.lang.Runtime 就是经典的单例模式。

经验分享 程序员 微信小程序 职场和发展