• 单例模式,学习笔记


    一、单例模式实现三要素:

    ●只能有一个实例。
      ◆构造器私有化

    ●自行创建这个实例
      ◆含有一个该类的静态变量来保存这个唯一的实例
    ●必须自行向整个系统提供这个实例;
      ◆对外提供获取该实例对象的方式:
      (1)直接暴露

      (2)用静态变量的get方法获取

    二、单例模式分类

    根据对象创建的时机不同,单例模式可以分为两类。一种是在类初始化的时候直接创建对象,称为饿汉式;另一种是在调用类静态方法时才创建对象,称为懒汉式。

    三、饿汉式

    饿汉式是线程安全的。

    1.直接实例化饿汉式

    public class Singleton {
        public static final Singleton INSTANCE = new Singleton();  //final修饰,强调这是一个单例
        private Singleton(){}
    
    }

     2.枚举类饿汉式

    public enum Singleton {
        INSTANCE;
    }

    3.静态代码块方式

    public class Singleton {
        public static final Singleton INSTANCE;  //final修饰,强调这是一个单例
        static {
            INSTANCE = new Singleton();
        }
        private Singleton(){}
    
    }

     这种方式适合于需要通过加载外部文件,来实例化单例对象属性的时候。

    例如:

    public class Singleton1 {
        public static final Singleton1 INSTANCE;
        private String name;
        
        static {
            INSTANCE = new Singleton1();
            try {
                InputStream inputStream = Singleton1.class.getClassLoader().getResourceAsStream("singleton.properties");
                Properties properties = new Properties();
                properties.load(inputStream);
                String name = properties.getProperty("singleton1.name");
                INSTANCE.name = name;
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
        
        private Singleton1(){}
    
        public String getName() {
            return name;
        }
    }
    View Code

    四、懒汉式

    方式一:

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

    注:此方式有线程安全问题,只适用于单线程环境。

    方式二:同步代码块

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

    注:此方式虽然解决了线程安全问题,但是效率低,不推荐使用

    方式三:

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

     效率比前一种高,推荐使用

    方式四:静态内部类(强烈推荐使用)

    public class Singleton {
        private Singleton(){
    
        }
    
        private static class Inner{
            private static final Singleton INSTANCE = new Singleton();
        }
    
        public static Singleton getInstance(){
            return Inner.INSTANCE;
        }
    }

    注:

    在内部类被加载和初始化时,才创建工 NSTANCE实例对象。

    静态内部类不会自动随着外部类的加载和初始化而初始化,它是要单独去加载和初始化的。因为是在内部类加载和初始化时,创建的,因此是线程安全的。

  • 相关阅读:
    python(十二)面向对象编程、类
    如何搭建测试环境
    python(十一)接口开发、写日志、发邮件、python来发请求、手动添加环境变量
    python(十):模块相关、操作Redis、操作Excel
    Python(九):递归+内置函数+第三方模块+md5加密+操作mysql
    Python(八) 函数、模块
    python练习题
    Python(七) 元组+集合+随机+string
    Python(六)操作文件+非空即真
    VUE基础-1
  • 原文地址:https://www.cnblogs.com/bear7/p/13403382.html
Copyright © 2020-2023  润新知