单例模式

Posted 燚夜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式相关的知识,希望对你有一定的参考价值。

单例模式(singleton)

有些时候,允许自由创建某个类的实例没有意义,还可能造成系统性能下降。如果一个类始终只能创建一个实例,则这个类被称为单例类,这种模式就被称为单例模式。

一般建议单例模式的方法命名为:getInstance(),这个方法的返回类型肯定是单例类的类型了。getInstance方法可以有参数,这些参数可能是创建类实例所需要的参数,当然,大多数情况下是不需要的。

单例的目的:保证一个类只有单一的实例,也就是说你无法通过new来创建这个类的一个新实例。

单例的好处:当一个对象在程序内部只能有一个实例的时候,它可以保证我们不会重复创建,而是始终指向同一个对象。

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。

 第一种:在声明变量时实例化(也叫饿汉式单例模式),代码如下:

public class Singleton {

      private static Singleton instance = new Singleton(); //已经自行实例化

      private Singleton(){}  //私有的默认构造

  public static Singleton getInstance() { //静态工厂方法

       return instance;  

   } 

 } 

第二种:把对象的创建放到方法里面去(也叫懒汉式单例模式),代码如下:

public class Singleton { 

  private static Singleton instance = null;

        private Singleton(){}

  public static synchronized Singleton getInstance() {

       //也可以这样写:synchronized public static Singleton getInstance() {

      if (instance == null){

       instance = new Singleton();

           }

           return instance; 

     } 

} 

各自的优缺点:

    第一种饿汉式:

    优点:在类加载初始化的时候就创建对象,调用getInstance的时候,没有同步方法,运行时性能较高。

    缺点:类加载速度慢,占用太多大的资源空间。

   第二种懒汉式:

    优点:避免了第一种方式的缺点, 同时,可以在多线程下运行安全。

    缺点:因为他使用了锁,在运行中效率慢。

加同步锁提高运行效率的懒汉模式实现方式一:

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

synchronized同步块括号中的锁定对象是采用的一个无关的Object类实例,而不是采用this,因为getInstance是一个静态方法,在它内部不能使用未静态的或者未实例的类对象,因此也可以用下面的方法来实现:

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

 

不加锁实现单例模式:可以先建立抽象类

/// <summary>
    /// 禁止在继承此类的任何类,使用成员变量
    /// </summary>
    public abstract class Singleton<T> where T : class, new()
    {
        private static T _instance;

        /// <summary>
        ///     获取该类的全局唯一实例
        /// </summary>
        /// <returns></returns>
        public static T Instance
        {
            get
            {
                if (_instance != null)
                {
                    return _instance;
                }
                return _instance = new T();
            }
        }
    }

所有需要使用单例模式的实体,只需要继承此抽象类即可

public class MyClass: Singleton<MyClass>
{}

 

以上是关于单例模式的主要内容,如果未能解决你的问题,请参考以下文章

常用代码片段

性能比较好的单例写法

片段作为 Android 中的单例

单例片段或保存网页视图状态

你熟悉的设计模式都有哪些?写出单例模式的实现代码

单例模式以及静态代码块