new 操做的底层过程: java
1. 为对象分配内存空间多线程
2. 初始化对象jvm
3. 将内存空间地址赋给对象引用变量线程
注意,上述过程的 2,3 次序可能会颠倒。所以,在多线程的环境下直接 new Instance() 会出现问题,,即线程2访问对象的时候该对象还未初始化。而用 volatile 修饰对象可强制 2,3过程不会从新排序。 (jdk 5 以上) code
** 然而,你不能保证全部的jvm都很好的实现了 这个内存模型,因此这可能仍是会有一些问题。因此最可靠的方式仍是用static (恶汉式)对象
package designpattern.singleton; /** * 使用双重检查锁定 机制实现单例模式 * @author Administrator * */ public class Singleton { /** * 这里要加 volatile修饰,保证在对象初始化后才将对象引用赋值 */ private volatile static Singleton singleton; private Singleton() { } public static Singleton getInstance() { if (singleton == null) { // 第一次检查 synchronized (Singleton.class) { if (singleton == null) // 第二次检查 singleton = new Singleton(); } } return singleton; } }
参考:http://www.infoq.com/cn/articles/double-checked-locking-with-delay-initialization排序