设计模式——单例模式

1.1、概念

定义:确保一个类只有一个实例,且自动实例化并向整个系统提供这个实例

特点:

成员变量:private static final

构造函数私有化

只提供getInstance()方法获取对象实例

1.2、应用

1.2.1、优缺点

  • 优点:

    1. 减少内存开支
    2. 减少系统性能消耗
    3. 避免对资源的多重占用(多个实例写同一个文件)
    4. 设置全局的访问点,优化和共享资源访问
  • 缺点:

    1. 没有接口,扩展困难
    2. 对测试不利
    3. 与单一职责原则有冲突(单一职责原则要求一个类应该只实现一个逻辑)

1.2.2、使用场景

  1. 生成唯一序列号的环境
  2. 需要一个共享访问点或共享数据
  3. 创建一个对象需要消耗的资源过多
  4. 需要定义大量的静态厂里和静态方法

1.3、单例模式的实现方式(五种)

1.3.1、饿汉式单例

public class Singleton{    
    private static final Singleton singleton=new Singleton();    
    private Singleton(){}    
    public static Singleton getInstance(){   
        return singleton;    
    } 
}

类的加载时就会实例化,且只加载一次,只传创建一个实例

优点:写法简单,避免线程问题

缺点:如果始终没有用过这个实例,就会造成内存浪费

1.3.2、懒汉式单例

public class Singleton{
    private static Singleton singleton=null;  
    private Singleton(){}
    public static Singleton getInstance(){        
        if(this.singleton==null){            
            this.singleton=new singleton();        
        }
        return singleton;    
    }
}

单例被延迟加载,只有使用的时候才会实例化

注意:懒汉式单例在高并发的情况下会出现多个实例的情况

描述:高并发下,当一个线程A执行到 this.singleton=new singleton(); ,但还没有获取对象时(对象初始化需要时间),第二个线程B执行到 if(this.singleton==null) 判断,那么线程B获得判断条件也是为真,于是两个线程都获得了对象,内存中就出现了两个对象。

优点:懒加载,避免内存浪费

缺点:线程安全问题

1.3.3、双重锁式单例

//解决线程安全问题,增加Synchronized
public class Singleton{
    private static Singleton singleton=null;  
    private Singleton(){}
    public static Singleton getInstance(){
        //先判断是否存在,不存在再加锁处理
        if(this.singleton==null){
            //在同一个时刻加了锁的那部分程序只有一个线程可以进入
            synchronized(Singletonc.class){
                if(this.singleton==null){
                    this.singleton=new singleton();  
                }
            }      
        }
        return singleton;    
    }
}

综合了懒汉式和饿汉式两者的优缺点整合而成。既保证了线程安全,又比直接上锁提高了执行效率,还节省了内存空间。

1.3.4、静态内部类(最推荐使用)

public class Singleton {

    private Singleton() {}

    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

与双重锁类似,但实现更简单。只有在调用 getInstance()时才会实例化。

1.3.5、枚举单例(不常用)

public enum Singleton {
    INSTANCE;
    //可以getInstance方法,通过Singleton.INSTANCE进行操作
}

1.4、扩展:有上限的多例模式

要求一个类只能产生有限个数的实例对象

public class Singleton{  
    //定义最多能产生的实例数量
    private static int maxNum=3;
    //定义一个List,存放实例
    private static List<Singleton> singletonList=new ArrayList<Singleton>();
    
    static{
        for(int i=0:i<maxNum;i++){
            singletonList.add(new Singleton())
        }
    }
    
    private Singleton(){}
    public static Singleton getInstance(){
        //随机获取一个实例
        Random random=new Random();
        return singletonList.get(random.nextInt(maxNum));    
    } 
}
上一篇:Permission denied: 'C:\\Users\\Admin\\AppData\\Local\\Temp\\tmp06sdogpt.py'


下一篇:单例模式之C++实现