zoukankan      html  css  js  c++  java
  • 单例模式,学习笔记

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

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

    ●自行创建这个实例
      ◆含有一个该类的静态变量来保存这个唯一的实例
    ●必须自行向整个系统提供这个实例;
      ◆对外提供获取该实例对象的方式:
      (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实例对象。

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

  • 相关阅读:
    LINQ to XML 示例(转)
    (jQuery,Highcharts)前端图表系列之一 Highcharts (转)
    c#中Split等分割字符串的几种方法(转)
    Highcharts 强大的jQuery图表制作功能
    OpenFileDialog、SaveFileDialog常用屬性、對話框用法及得到系統特殊文件夾路徑(转)
    C# Regex 深入正则表达式(转)
    C#文件IO操作(转)
    免费Google地图API使用说明(转)
    Java遍历集合的几种方法分析(实现原理、算法性能、适用场合)
    C++ Web 开发框架 (CppCMS)
  • 原文地址:https://www.cnblogs.com/bear7/p/13403382.html
Copyright © 2011-2022 走看看