1、细说Singleton模式 创建、多线程与销毁 二,2.多线程在解一中,如果我们运行在多线程的环境中,该方案是完美的么,将会有什么后果呢?后果就是会造成内存泄漏,并且有可能前后获取的Singleton对象不一样(原因请自己思考,后面有解答)。为了解决这个问题,将解一的Instance改为如下:38.Singleton /3,42.43.UnLock(m_mutex); /444.return *m_pInstance; /545.46.此种方法将解决解一运行在多线程环境下内存泄漏的问题,但带来的结果是,当m_mutex被锁定时,其它试图锁定m_mutex的线程都将必须等等。并且每次执行锁操作其
2、付出的代价极大,亦即是这种方案的解决办法并不吸引人。,那么我们将上面的代码改为如下方式:47.Singleton /5,54.55.这样修改的结果没有问题了么?NO!该方案带来的结果同解一,原因也一样,都将造成内存泄漏。此时“双检测锁定”模式就粉墨登场了。由Doug Schmidt和Tim Harrison提出了“双检测锁定”(Double-Checked Locking)模式来解决multithread singletons问题。56.Singleton /4,61.UnLock(m_mutex); /562.63.return *m_pInstance; /664.请看上面的第三句,这句话
3、是不是具有化腐朽为神奇的力量啊 _上面的方案就完美了么。回答还是NO!(各位看官是否已经郁闷了啊,这不是玩我啊?请耐心点,听我细细到来_)如果在RISC机器上编译器有可能将上面的代码优化,在锁定m_mutex前执行第3句。这是完全有可能的,因为第一句和第3句一样,根据代码优化原则是可以这样处理的。这样一来,我们引以为自豪的“双检测锁定”居然没有起作用( L),怎么办?解决呗。怎么解决?简单,我们在m_pInstance前面加一个修饰符就可以了。什么修饰符呢?volatile(简单吧)那么我们完整的解法如下:65./*解三*/66.class Singleton67.68.public:69.s
4、tatic Singleton &Instance() /170.if( !m_pInstatnce) /271.Lock(m_mutex) /3,72.If( !m_pInstance ) /473.m_pInstance = new Singleton;/574.UnLock(m_mutex); /675.76.return *m_pInstance; /777.78.private:79.static volatitle Singleton *m_pInstatnce; /8,80.private:81.Singleton(); /982.Singleton(const Singleton /13 java培训 http:/