美文网首页Java 杂谈
设计模式-单例模式

设计模式-单例模式

作者: breezedancer | 来源:发表于2016-10-28 15:12 被阅读0次

单例模式有3个特点:一是某个类在某个上下文当中有且仅有一个实例;二是这个实例是自己创造出来的,别的类不好代办;三是在整个系统当中他必须能够提供这个单例。

可以得出单例的类必须包含自己的一个静态属性,自己的构造方法为私有,确保外界无法实例化,提供一个静态方法,该方法实例化静态属性并且向外提供这个实例。

他的 UML 图如下:


该模式的使用条件是在环境下只需一个实例,就可以使用该模式;比如在现今中国(环境),说国家主席这个类就自然想到习大大,那么这个就是单例模式,所有需要国家主席解决的都到习大大这里,没有第二个。

单例最简单的实现如下代码:

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

这个属于懒汉模式,需要实例化的找我,但是也是线程不安全的;同时有2个线程同时调用 getInstance 方法可能会各自实例化各自的单例,这就不对了。改进下,把方法修改为public static synchronized Singleton getInstance()增加同步块,可能每次都同步下又有性能丢失。

那么这次把实例化放到类装载时看看,就形成了饿汉模式,迫不及待的先行实例化

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

这个没有达到懒加载,我压根在环境里就不需要你这个单例,你给实例化出来干什么呢?或者有其他的情况导致类加载也会出现问题。

再进行改变,使用内部类

public class SingletonClass {
    private SingletonClass() {
    }
    public static SingletonClass getInstance() {
        return SingletonInnerClass.sc;
    }
    private static class SingletonInnerClass {
        private static SingletonClass sc = new SingletonClass();
    }
}

这个方式是即使父类实例化了,内部类也不一样实例化,只有显示调用 getInstance 才可以显示装载内部类,从而达到实例化的效果。

使用枚举类来实现,是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。

enum Singleton {  
  INSTANCE;  
  public static Singleton getInstance() {  
    return INSTANCE;  
  }  
} 

最后是双重检验来实现,确保唯一实例

public class DoubleCheckedLockingSingleton{
     private volatile DoubleCheckedLockingSingleton INSTANCE;
     private DoubleCheckedLockingSingleton(){}
     public DoubleCheckedLockingSingleton getInstance(){
         if(INSTANCE == null){
            synchronized(DoubleCheckedLockingSingleton.class){
                //双重检验单例模式
                if(INSTANCE == null){
                    INSTANCE = new DoubleCheckedLockingSingleton();
                }
            }
         }
         return INSTANCE;
     }
}

众多提倡的枚举类型,但在安卓开发过程中不太建议使用。单例模式使用频率非常高的一个模式,针对上面种种情况,需要各自筛选选用,并非都合适或不合适,尤其是最后的双重校验,在 java 编译器中,DoubleCheckedLockingSingleton类的初始化和INSTANCE变量赋值的顺序不可预料,有可能发生崩溃的危险。

与单例对应的是多例模式,多例模式是单例模式的扩展版本,比如一个系统需要支持多国语言,每个语言就是一个实例,那么久需要对若干个国家语言实例化,但不能从外界去 new 操作实例化,仍然需要配合参数从该类获取特定的实例。其主要思路还是构造方法私有化,包括有参数的构造方法和无参数的构造方法都要私有化,仍然对外界提供实例,根据参数决定提供何种实例。

相关文章

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • python中OOP的单例

    目录 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 单例

    目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 设计模式 - 单例模式

    设计模式 - 单例模式 什么是单例模式 单例模式属于创建型模式,是设计模式中比较简单的模式。在单例模式中,单一的类...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • python 单例

    仅用学习参考 目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计...

  • 基础设计模式:单例模式+工厂模式+注册树模式

    基础设计模式:单例模式+工厂模式+注册树模式 单例模式: 通过提供自身共享实例的访问,单例设计模式用于限制特定对象...

  • 单例模式

    JAVA设计模式之单例模式 十种常用的设计模式 概念: java中单例模式是一种常见的设计模式,单例模式的写法...

  • 设计模式之单例模式

    单例设计模式全解析 在学习设计模式时,单例设计模式应该是学习的第一个设计模式,单例设计模式也是“公认”最简单的设计...

网友评论

    本文标题:设计模式-单例模式

    本文链接:https://www.haomeiwen.com/subject/ieleuttx.html