日期:2014-05-20  浏览次数:20662 次

[40分:结贴超快]singleton模式同步锁问题

double-check locking:
第一种方式:
Java code

public class Singleton {
    private static Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance() {
        if (instance == null){
            synchronized(Singleton.class){
                if(instance == null) {
                     instance = new Singleton();
                }
            }
        }
        return instance;
    }
}



第二种方式:
Java code

public class Singleton {
    private static Singleton instance = null;
    private static final Object object = new Object();
    private Singleton(){}
    public static Singleton getInstance() {
        if (instance == null){
            synchronized(object){
                if(instance == null) {
                     instance = new Singleton();
                }
            }
        }
        return instance;
    }
}



三:另外的实现方式:

2>下面的这种方式呢?
Java code

public class Singleton { 
    private static Singleton instance = new Singleton(); 

    private Singleton() { 
        // .... 
    } 

    public static Singleton getInstance() { 
        return instance; 
    } 

    // 其它实作 
}



3>另外这种方式?
Java code

public class Singleton {
    private static class SingletonHolder {
        static final Singleton instance = new Singleton();
    }
    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}



问题1:

1>请问第一种方式和第二种方式有什么区别?
  性能方面呢?

2>另外的方式有什么区别?
  性能?安全性?


------解决方案--------------------
前2种有区别么?都是延迟初始化,用双重锁检查。
一个object 一个Singleton.class。 jdk1.5以前别用这种模式,会出问题的。就是1.5以后也要用volatile fix一下(private static volatile Singleton instance = null)

后面2种有区别么?只是写法不一样罢了,都是预先初始化。这种方式没有问题,哪都能用。
------解决方案--------------------
我比较喜欢使用最后一种方式,也就是你所说的“另外的一种方式”。前两种原理是一样的,基本没什么区别
第三中很显然不能解决并发的问题,如果不需要并发处理,建议使用第三种,因为性能上有保障啊。如果既要考虑并发又要考虑性能,则选择最后一种方式