加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

设计模式之单例模式介绍

发布时间:2021-12-10 13:39:52 所属栏目:PHP教程 来源:互联网
导读:单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。其构造过程由自身完成,可以将构造方法定义为private型的,这样外界就只能通过定义的静态的函数Instance()构造实例,这个函数的目的就是返回一个类的实例,在此方法中去做是

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。其构造过程由自身完成,可以将构造方法定义为private型的,这样外界就只能通过定义的静态的函数Instance()构造实例,这个函数的目的就是返回一个类的实例,在此方法中去做是否有实例化的判断。客户端不再考虑是否需要去实例化的问题,把这些都交给了单例类自身。通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法,就是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。
 
C++版本:
 
template <class T>
    class Singleton
    {
    public:
        static inline T* Instance();
        static inline void ReleaseInstance();
 
    private:
        Singleton(void){}
        ~Singleton(void){}
        Singleton(const Singleton&){}
        Singleton & operator= (const Singleton &){}
 
        static std::auto_ptr<T> m_instance;
        static ThreadSection m_critSection;
    };
 
    template <class T>
    std::auto_ptr<T> Singleton<T>::m_instance;
 
    template <class T>
    ThreadSection Singleton<T>::m_critSection;
 
    template <class T>
    inline T* Singleton<T>::Instance()
    {
        AutoThreadSection aSection(&m_critSection);
        if( NULL == m_instance.get())
        {
            m_instance.reset ( new T);
        }
 
        return m_instance.get();
    }
    template<class T>
    inline void Singleton<T>::ReleaseInstance()
    {
        AutoThreadSection aSection(&m_critSection);
        m_instance.reset();
    }
 
#define DECLARE_SINGLETON_CLASS( type )
    friend class std::auto_ptr< type >;
        friend class Singleton< type >;
 
多线程时Instance()方法加锁保护,防止多线程同时进入创建多个实例。m_instance为auto_ptr指针类型,有get和reset方法。发现好多网上的程序没有对多线程进行处理,笔者觉得这样问题很大,因为如果不对多线程处理,那么多线程使用时就可能会生成多个实例,违背了单例模式存在的意义。加锁保护就意味着这段程序在绝大部分情况下,运行是没有问题的,这也就是笔者对自己写程序的要求,即如果提前预料到程序可能会因为某个地方没处理好而出问题,那么立即解决它;如果程序还是出问题了,那么一定是因为某个地方超出了我们的认知。
 
再附一下Java版的单例模式:
 
public class Singleton {
    private Singleton() {       
    }
   
    private static Singleton single = null;
   
    public static Singleton getInstance() {
        if (single == null) {
            synchronized (Singleton.class) {
                if (single == null) {
                    single = new Singleton();
                }               
            }
        }
       
        return single;
    }
}
 
上述代码中,一是对多线程做了处理,二是采用了双重加锁机制。由于synchronized每次都会获取锁,如果没有最外层的if (single == null)的判断,那么每次getInstance都必须获取锁,这样会导致性能下降,有了此判断,当生成实例后,就不会再获取锁。

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读