• 设计模式——单例


    下面我会讲五种常用实现

    晚上睡不着,那就把设计模式再看一下吧,顺便写一篇文章,如果有问题,欢迎斧正,谢谢。
    首先介绍一下单例模式。也是最长用的。通常加载配置啊都会用到。

    源码地址:https://github.com/DeveloperZJQ/scalavsjava/tree/master/src/main/java/designpatterns/singleton

    • 饿汉式
    • 懒汉式
    • 静态内部类
    • 双重检查锁
    • 枚举类

    饿汉式

    直接上代码

    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    /**
     * @author happy
     * @since 2020-10-09
     * 饿汉式 方式一 : 静态常量饿汉式
     */
    public class StarvationSingleton {
    
        private static final StarvationSingleton starvationInstance = new StarvationSingleton();
    
        private StarvationSingleton() {
        }
    
        ;
    
        public static StarvationSingleton getInstance() {
            return starvationInstance;
        }
    
        /**
         * read local file
         */
        public Properties getFileConfig(String fileName) {
            Properties pro = new Properties();
            InputStream resourceAsStream = StarvationSingleton.class.getClassLoader().getResourceAsStream(fileName);
            try {
                pro.load(resourceAsStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return pro;
        }
    
        public static void main(String[] args) {
            StarvationSingleton instance1 = StarvationSingleton.getInstance();
            StarvationSingleton instance2 = StarvationSingleton.getInstance();
            System.out.println(instance1==instance2);
            System.out.println(instance1);
            System.out.println(instance2);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    说明:饿汉式,上来就new,不用关系到底实例是否存在,多线程情况下不会用到该方法。

    懒汉式

    直接上代码

    懒汉式单例懒加载,不能解决线程安全问题、

    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    /**
     * @author happy
     * @since 2020-10-09
     * 懒汉式 方式二
     */
    public class LazyOf2LockSingleton {
        private static LazyOf2LockSingleton lazyOf2LockSingleton;
    
        private LazyOf2LockSingleton() {
        }
    
        ;
    
        public static LazyOf2LockSingleton getInstance() {
                    if (lazyOf2LockSingleton == null) {
                        lazyOf2LockSingleton = new LazyOf2LockSingleton();
                    }
            return lazyOf2LockSingleton;
        }
    
        //get local file config
        public Properties getFileConfig(String fileName) {
            Properties pro = new Properties();
            InputStream resourceAsStream = LazyOf2LockSingleton.class.getClassLoader().getResourceAsStream(fileName);
    
            try {
                pro.load(resourceAsStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return pro;
        }
    
        public static void main(String[] args) {
            Properties fileConfig = getInstance().getFileConfig("demo.properties");
            System.out.println(fileConfig);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    说明:多线程下不能用该方式。

    静态内部类

    直接上代码

    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    /**
     * @author happy
     * @since 2020-10-09
     */
    public class StaticInnerSingleton {
        private StaticInnerSingleton(){};
    
        private static class StaticInnerSingletonInstance{
            private static final StaticInnerSingleton instance = new StaticInnerSingleton();
        }
    
        public static StaticInnerSingleton getInstance(){
            return StaticInnerSingletonInstance.instance;
        }
    
        //get local file config
        public Properties getFileConfig(String fileName){
            Properties pro = new Properties();
            InputStream resourceAsStream = LazyOf2LockSingleton.class.getClassLoader().getResourceAsStream(fileName);
    
            try {
                pro.load(resourceAsStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return pro;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    说明:适用于多线程,该方式在多个框架源码中存在,它兼顾了懒汉式的懒加载,又保证了多线程下只存在一个单例。

    双重检查锁

    直接上代码
    懒汉式单例-双重锁
    解决线程安全问题、同时解决懒加载问题

    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    /**
     * @author happy
     * @since 2020-10-09
     * 懒汉式 方式二
     */
    public class LazyOf2LockSingleton {
        //volatile 保证可见性
        private static volatile LazyOf2LockSingleton lazyOf2LockSingleton;
    
        private LazyOf2LockSingleton() {
        }
    
        ;
    
        public static LazyOf2LockSingleton getInstance() {
            if (lazyOf2LockSingleton == null) {
                synchronized (LazyOf2LockSingleton.class) {
                    if (lazyOf2LockSingleton == null) {
                        lazyOf2LockSingleton = new LazyOf2LockSingleton();
                    }
                }
            }
            return lazyOf2LockSingleton;
        }
    
        //get local file config
        public Properties getFileConfig(String fileName) {
            Properties pro = new Properties();
            InputStream resourceAsStream = LazyOf2LockSingleton.class.getClassLoader().getResourceAsStream(fileName);
    
            try {
                pro.load(resourceAsStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return pro;
        }
    
        public static void main(String[] args) {
            Properties fileConfig = getInstance().getFileConfig("demo.properties");
            System.out.println(fileConfig);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    说明:充分保证多线程下安全,兼具懒加载优势。

    枚举类

    直接上代码
    1)线程安全问题。因为Java虚拟机在加载枚举类的时候会使用ClassLoader的方法,这个方法使用了同步代码块来保证线程安全。
    2)避免反序列化破坏对象,因为枚举的反序列化并不通过反射实现。

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;

    /**

    • @author happy

    • @since 2020-10-09
      */
      public enum EnumSingleton {
      INSTANCE;

      //get local file config
      public Properties getFileConfig(String fileName) {
      Properties pro = new Properties();
      InputStream resourceAsStream = LazyOf2LockSingleton.class.getClassLoader().getResourceAsStream(“demo.properties”);
      try {
      pro.load(resourceAsStream);
      } catch (IOException e) {
      e.printStackTrace();
      }
      return pro;
      }

      public static void main(String[] args) {
      Properties fileConfig = INSTANCE.getFileConfig(“”);
      System.out.println(fileConfig);
      }
      }
      说明:天然保证线程安全,代码简单,推荐使用。

  • 相关阅读:
    计算机毕业设计之java+javaweb的面向学生成绩分析系统
    避免项目延期,有效推进项目进度的4大关键方法
    金九银十招聘季, APP测试面试题助你拿高薪Offer
    C#中使用Newtonsoft.Charp实现Json对象序列化与反序列化
    数据解析——BeautifulSoup4
    SAM + YOLOv8 图像分割及对象检测
    infoNCE损失和互信息的关系
    Nginx:移植Nginx内存池 | 附测试用例
    【ManageEngine】网络带宽管理工具
    论文复现|Panoptic Deeplab(全景分割PyTorch)
  • 原文地址:https://blog.csdn.net/u010772882/article/details/126564203