设计模式——单例模式

Posted 入坑的读书人

tags:

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

、单例模式(Singleton

单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:

  • 对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中。
  • 保持程序运行的时候该中始终只有一个实例存在内存中

 

看看下面一个简单的例子:

 

public class Singleton {  

  

    /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */  

    private static Singleton instance = null;  

  

    /* 私有构造方法,防止被实例化 */  

    private Singleton() {  

    }  

  

    /* 静态工程方法,创建实例 */  

    public static Singleton getInstance() {  

        if (instance == null) {  

            instance = new Singleton();  

        }  

        return instance;  

    }  

  

    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  

    public Object readResolve() {  

        return instance;  

    }  

}

 

观察一下上面的Singleton这个类,基本可以实现要求,但是仔细观察,可以发现这样做丝毫没有线程安全保护,对吧!有人肯定会说这个简单只要在静态工程方法【getInstance()】前加一个synchronized关键字,就解决了?是的这样做的确提高了安全性,但是这样每次调用getInstance()就都要锁,性能对对象上一定会下降的。那怎么做?看下面

 

public static Singleton getInstance() {  

        if (instance == null) {  

            synchronized (instance) {  

                if (instance == null) {  

                    instance = new Singleton();  

                }  

            }  

        }  

        return instance;  

}

事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了~还有什么问题呢,再仔细想想,因为synchronized关键字在内部,而且加了判断只有instancenull时候,才需要加锁。其中instance = new Singleton();  是分两步的包括创建和赋值,而jvm中不能保证两者的先后顺序。所以我们只能这样做。

 

private static class SingletonFactory{           

        private static Singleton instance = new Singleton();           

    }           

    public static Singleton getInstance(){           

        return SingletonFactory.instance;           

}

 

实际情况是,单例模式使用内部类来维护单例的实现,JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题。这样我们暂时总结一个完美的单例模式:

 

public class Singleton {  

  

    /* 私有构造方法,防止被实例化 */  

    private Singleton() {  

    }  

  

    /* 此处使用一个内部类来维护单例 */  

    private static class SingletonFactory {  

        private static Singleton instance = new Singleton();  

    }  

  

    /* 获取实例 */  

    public static Singleton getInstance() {  

        return SingletonFactory.instance;  

    }  

  

    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  

    public Object readResolve() {  

        return getInstance();  

    }  

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

单例模式单例模式精讲(上)

单例模式(单例设计模式)详解

单例模式(饿汉式单例模式与懒汉式单例模式)

设计模式之单例模式

什么是单例设计模式

Java设计模式-单例模式