zoukankan      html  css  js  c++  java
  • 设计模式之单例模式

    所谓单例,就是整个程序有且仅有一个实例。该类负责创建自己的对象,同时确保只有一个对象被创建。在Java,一般常用在工具类的实现或创建对象需要消耗资源。

    特点:

    • 类构造器私有
    • 持有自己类型的属性
    • 对外提供获取实例的静态方法

    第一种:饿汉模式

     1 /**
     2  * 饿汉模式
     3  * 线程安全,比较常用,但容易产生垃圾,因为一开始就初始化
     4  */
     5 public class Singleton {
     6     private final static Singleton instance = new Singleton();
     7 
     8     private Singleton(){ }//内部定义实例
     9 
    10     public static Singleton getInstance(){
    11         return instance;
    12     }
    13 }

    第二种:懒汉模式

     1 /**
     2  * 懒汉模式
     3  * 线程不安全,延迟初始化,严格意义上不是不是单例模式
     4  */
     5 public class Singleton{
     6     private static Singleton instance;
     7 
     8     private Singleton(){}
     9 
    10     public static Singleton getInstance(){
    11         if(instance==null){
    12             instance = new Singleton();
    13         }
    14         return instance;
    15     }
    16 }

    第三种:双重锁模式

     1 /**
     2  * 双重锁模式
     3  * 线程安全,延迟初始化。这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
     4  * 双重检查模式,进行了两次的判断,第一次是为了避免不要的实例,第二次是为了进行同步,避免多线程问题。
     5  * 由于singleton=new Singleton()对象的创建在JVM中可能会进行重排序,在多线程访问下存在风险,
     6  * 使用volatile修饰signleton实例变量有效,解决该问题。
     7  */
     8 
     9 public class Singleton {
    10     private volatile static Singleton singleton;
    11     private Singleton (){}
    12     public static Singleton getSingleton() {
    13         if (singleton == null) {
    14             synchronized (Singleton.class) {
    15                 if (singleton == null) {
    16                     singleton = new Singleton();
    17                 }
    18             }
    19         }
    20         return singleton;
    21     }
    22 }

    第四种:静态内部单例模式

     1 /**
     2  * 静态内部类单例模式
     3  * 只有第一次调用getInstance方法时,虚拟机才加载 Inner 并初始化instance ,
     4  * 只有一个线程可以获得对象的初始化锁,其他线程无法进行初始化,保证对象的唯一性。
     5  * 目前此方式是所有单例模式中最推荐的模式,但具体还是根据项目选择。
     6  */
     7 
     8 public class Singleton {
     9     private Singleton(){
    10     }
    11     public static Singleton getInstance(){
    12         return Inner.instance;
    13     }
    14     private static class Inner {
    15         private static final Singleton instance = new Singleton();
    16     }
    17 }

    第五种:枚举单例模式

    1 /**
    2  * 枚举单例模式
    3  * 默认枚举实例的创建是线程安全的,并且在任何情况下都是单例。
    4  */
    5 public enum Singleton {
    6     INSTANCE;
    7 }

    实际上

    • 枚举类隐藏了私有的构造器。
    • 枚举类的域 是相应类型的一个实例对象

    那么枚举类型日常用例是这样子的:

     1 public enum Singleton  {
     2     INSTANCE;
     3 
     4     //doSomething 该实例支持的行为
     5 
     6     //可以省略此方法,通过Singleton.INSTANCE进行操作
     7     public static Singleton get Instance() {
     8         return Singleton.INSTANCE;
     9     }
    10 }

      枚举单例模式在《Effective Java》中推荐的单例模式之一。但枚举实例在日常开发是很少使用的,就是很简单以导致可读性较差。
    在以上所有的单例模式中,推荐静态内部类单例模式。主要是非常直观,即保证线程安全又保证唯一性。
    众所周知,单例模式是创建型模式,都会新建一个实例。那么一个重要的问题就是反序列化。当实例被写入到文件到反序列化成实例时,我们需要重写readResolve方法,以让实例唯一。

  • 相关阅读:
    记一次省赛总结
    护网杯一道密码学的感想
    配置phpstudy+phpstorm+xdebug环境
    python 模板注入
    hash扩展攻击本地实验
    kali rolling更新源之gpg和dirmngr问题
    web信息泄露注意事项
    ctf常见php弱类型分析
    文件上传小结
    ctf变量覆盖漏洞
  • 原文地址:https://www.cnblogs.com/donleo123/p/11649051.html
Copyright © 2011-2022 走看看