四点要求:唯一实例,多线程并发访问,效率性能,懒加载(Lazy Load,在需要的时候才被构造)。
注意私有化构造方法!
1、懒汉模式,线程不安全
/** * 实现单例访问Kerrigan的第一次尝试 */ public class SingletonKerriganA { /** * 单例对象实例 */ private static SingletonKerriganA instance = null; public static SingletonKerriganA getInstance() { if (instance == null) { //line A instance = new SingletonKerriganA(); //line B } return instance; } }
2、懒汉模式,线程安全,但低效
/** * 实现单例访问Kerrigan的第二次尝试 */ public class SingletonKerriganB { /** * 单例对象实例 */ private static SingletonKerriganB instance = null; public synchronized static SingletonKerriganB getInstance() { if (instance == null) { instance = new SingletonKerriganB(); } return instance; } }
3、双重锁定检查(DCL)。适用于JDK1.5之后。
/** * 实现单例访问Kerrigan的第四次尝试 */ public class SingletonKerriganD { /** * 单例对象实例 */ private volatile static SingletonKerriganD instance = null; public static SingletonKerriganD getInstance() { if (instance == null) { synchronized (SingletonKerriganD.class) { if (instance == null) { instance = new SingletonKerriganD();//并不是一个原子操作 } } } return instance; } }
4、饿汉模式。实例的创建是依赖参数或者配置文件的,在getInstance()之前必须调用某个方法设置参数给它,那样这种单例写法就无法使用了。
/** * 实现单例访问Kerrigan的第五次尝试 */ public class SingletonKerriganE { /** * 单例对象实例 */ private static SingletonKerriganE instance = new SingletonKerriganE(); public static SingletonKerriganE getInstance() { return instance; } }
5、静态内部类。懒汉模式,线程安全,性能好,应用多。
/** * 实现单例访问Kerrigan的第六次尝试 */ public class SingletonKerriganF { private static class SingletonHolder { /** * 单例对象实例 */ static final SingletonKerriganF INSTANCE = new SingletonKerriganF(); } public static SingletonKerriganF getInstance() { return SingletonHolder.INSTANCE; } }
实际开发中,我们应该记住:没有最好的单例模式,只有最合适的单例模式。
参考:http://www.iteye.com/topic/575052