什么是单例模式,单例模式的优点,饿汉和懒汉式单例模式的区别

什么是单例模式,单例模式的优点,饿汉和懒汉式单例模式的区别

什么是单例模式

单例模式是一种设计模式,是创建式模式的一种。它确保了一个类有且只有一个对象存在。
单例模式的定义:
1:定义私有的静态成员变量private static
2:私有化构造函数private
3:提供一个公有的的静态方法以便构造实例public static

单例模式的优点和适用场景

优点:
1:避免了频繁的创建和销毁对象,减少了系统开销
2:节省了内存空间,且内存中只有一个对象
3:提供了一个全局访问点
适用场景:
1:针对某些需要频繁创建和删除对象的情景
2:需要频繁的创建对象,但对象创建需要大量的开销
3:某些确实只能有一个对象的情景,如某些核心交易类,就只许有一个对象

饿汉式和懒汉式单例模式区别

饿汉式:在单例类被加载时,就直接实例化一个对象
不关用不用的上,加载时就创建实例,浪费了空间,但是用的时候不需要判断是否需要创建实例,节约了判断的时间
属于空间换时间

...
private static Singleton instance=new Singleton();
...
public static Singleton getInstance(){
    
    
return instance;
}
...

懒汉式:单例类被加载时,先不实例化一个对象,在公有的静态方法被调用时,才会实例化一个对象
JVM加载完之后并不会创建实例,节省了空间,但是在每次获取实例的时候都要进行一次判断,看是否需要创建实例,浪费了时间
属于时间换空间

...
private static Singleton;
...
public static synchronized Singleton getInstance(){
    
    
if(instance==null)instance=new SIngleton();
}
...

而且由于懒汉式在加载类的时候并不创建实例,因此在真正创建实例时,有可能引发多线程并发问题,本来单例模式保证只有一个实例,由于多线程调用的问题,创建出多个实例来,导致单例模式失效。
因此,在公有静态方法上加了个synchronized(同步)关键字来保证线程安全,同一时间只有一个线程能访问该方法。
但紧接着问题又出现了,直接在方法上加锁确实简单,但也进一步加大了开销,拉低了整个实例的访问速度。

改进

方法:双重检查加锁
1:加volatile关键字,保证本地线程不会缓存该变量,变量的读写直接在共享内存中,这样使多线程读到的变量都是正确的
2:将synchronized(同步)关键字移入方法内部使用,当方法调用时,先检查是否需要创建实例,如果实例已经存在,直接返回实例,不需要使用同步关键字,如果实例不存在,则进入同步关键字判断,将判断实例是否存在的步骤再进行一遍。
在此过程中,检查了两次实例是否存在,还使用了同步关键字加锁,因此被叫做双重检查加锁

...
private volatile  static Singleton instance=null;
...
public static Singleton getInstance(){
    
    
if(instance==null)
	synchronized(Singleton.class)
	if(instance==null)instance=new Singleton();
return instance;	
	}
...

这样保证了线程的安全,而且只有第一次实现实例的时候会同步,减小了性能开销

猜你喜欢

转载自blog.csdn.net/qq_45347311/article/details/115266578