单例模式和多例模式(懒汉式和饿汉式)

2023-08-09 20:57:56 浏览数 (2)

一、什么是单例、多例:

所谓单例就是所有的请求都用一个对象来处理,比如我们常用的service和dao层的对象通常都是单例的,而多例则指每个请求用一个新的对象来处理,比如action;

二、单例模式和多例模式说明:

  1. 单例模式和多例模式属于对象模式。
  2. 单例模式的对象在整个系统中只有一份,多例模式可以有多个实例。
  3. 它们都不对外提供构造方法,即构造方法都为私有。

三、单例模式适用场景:

  1. 需要生成唯一序列的环境
  2. 需要频繁实例化然后销毁的对象。
  3. 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
  4. 方便资源相互通信的环境

四、举例

1、懒汉式

你用的时候,我再去给你创建对象

代码语言:javascript复制
class Singleton{
      private static Singleton single;
      
      private static Singleton(){}

     public static synchronized Singleton getInstance(){
        if(single==null)
            single =new Singleton();
        return single;
    }
}

优点: 第一次调用才初始化,避免浪费内存

缺点: 加锁了执行效率低

2、饿汉式

启动的时候就创建了对象,

代码语言:javascript复制
class SingleObj{
    //私有变量 
    private static SingleObj single=new SingleObj();          
   //私有构造函数 不能被实例化  
    private static SingleObj(){}

    public static SingleObj getInstance(){
    return single;    
  }      
}

优点: 没有加锁,执行效率更高

缺点: 类加载时就初始化,浪费内存

3、Double CheckLock实现单例:

Double CheckLock也就是双重锁判断机制(由于JVM底层模型原因,偶尔会出问题,

不建议使用),是在懒汉式单例上发展而来

代码语言:javascript复制
/**
*Double CheckLock实现单例
*Double CheckLock也就是双重锁判断机制(由于JVM底层模型原因,
*偶尔会出问题,不建议使用)
*/

public class SingletonThree {
    
private volatile static SingletonThree instance;

//私有化构造器
private SingletonThree() {
}

//静态工厂方法,双重锁判断机制
public static SingletonThree newInstance() {
    if (instance== null) {
        synchronized (SingletonThree.class) {
            if (instance== null) {
                instance= new SingletonThree();
            }
        }
    }
return instance;
    }
}
4、静态内部类模式:

特点:线程安全,调用效率高,可以延时加载

代码语言:javascript复制
/**
*静态内部类实现模式
*线程安全,调用效率高,可以延时加载
*/
public class SingletonFour {
    // 静态内部类
    private static class SingletonClassInstance {
        private static final SingletonFour instance= new SingletonFour();
}

// 私有化构造器
    private SingletonFour() {

    }

//静态工厂方法
    public static SingletonFour getInstance() {
        return SingletonClassInstance.instance;
    }
}
5、枚举类:

特点: 线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用;

描述: 这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。

这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。

不能通过 reflection attack 来调用私有构造方法。

代码语言:javascript复制
public class SingletonFive {

    //私有化构造器
    private SingletonFive(){

    }
    //使用枚举
    private static enum Singleton{
        INSTANCE;

        private SingletonFive singleton;
        //JVM会保证此方法绝对只调用一次
        private Singleton(){
            singleton = new SingletonFive();
        }
        public SingletonFive getInstance(){
            return singleton;
        }
    }

//静态工厂方法
    public static SingletonFive getInstance(){
    return Singleton.INSTANCE.getInstance();
    }
}

0 人点赞