一、首先从形而上角度看,我认为很多文章都在把两个指标(我称为单例指标和平安指标)混在一起谈。留神这是两个指标,1 是是否单例;2 是在多线程下是否牢靠。双重锁只是保障了指标 1,与指标 2 无关。其实你想一下,1 个 if 解决不了指标 2,2 个 if 就行了?那 3 个 if 岂不成果更好?
二、具体来看。有人说 1if 为效率(防止都申请锁)【我认为不精确】;2if 为防止反复 new。
(1)首先,双重查看锁不肯定非用到单例问题上。用到别处(2 中也未必是做 new 工作),可能 1,2 都为效率。
(2)就单例问题而言,1if 原本就是单例模式要求的,谈不上什么效率,2if 才是减少的,能防止反复 new,从而在多线程环境下没毁坏“指标 1”。
(3)至于指标 2,问题出在 p ==null 为假时。p 不空,不代表你马上应用就没问题(因为编译重排、硬件等各种起因,对象还没有初始化好就被你看到了)。这一点对 1if,2if 都实用,所以你就是加 3 个 if,或者加 volatile,也还是未必能保障你看到的、不空的 p 能用(前提是 p 是刚 new 的,只有是 new 的问题,那影响因素太多了:单例外部还有其余数据成员是否筹备好、编译优化、OS、多 CPU 调度、CPU 外部。。。)
(4)所以我感觉双重锁,只有是用在单例问题上,从根本上看是有平安问题的,只是在你某个具体平台上好使而已。
![3Y(LCJ2]T`SQN76BC29K8}U.png](/img/bVcZFTm)