<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近单例模式有点火,虽然还不太明白为什么,但在这里也做一个总结,顺带也检查下自己对于这个设计模式的掌握,好了,闲话不多说,直接上代码</span>
class Singleton { private Singleton(){}; private static final Singleton instance= new Singleton(); public static Singleton getInstance() { return instance; }
class Singleton { private Singleton(){}; private static Singleton instance; public static Singleton getInstance() { if (instance==null) { instance=new Singleton(); } return instance; } }
但渐渐地就有人发现这种模式的问题了,俗话说每一次优化都有可能带来新的问题,上面饿汉式在单线程环境下没有问题,但如果我是在多线程的条件下呢?两个线程一起访问getIntance方法怎么办,同时发现它是null怎么办?这不就违背了单例的初衷了么
所以就有了下面的改进版的懒汉式
public class Singleton { private static Singleton instance=null<span style="font-family: Arial, Helvetica, sans-serif;">; </span> private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
public class Singleton { private volatile static Singleton singleton=null; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }这也就是传说中的双重校验锁模式,不得不说想出这种模式的人,不可谓不强大,无比的纠结之心如滔滔洪水,在我的心中绵绵不绝,作者很犀利的看出了在多线程环境下,检测null操作与创建对象操作不一致的问题,它主要考虑的就是多线程的并发但我的心真的看的好纠结啊,还有没有更好的办法呢,就有了我第一次接触单例模式时想到的内部类解决方法
class Singleton { private Singleton(){}; private static class getSingletonInstance{ private static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return getSingletonInstance.instance; } }该方法,主要利用了内部类可以方便的访问外部类的成员变量就像访问自己的成员变量一样优点,因为没有静态属性,在虚拟机启动的时候并不会被初始化,知道调用getIntance方法才会产生具体的实例,而且内部类是static内部类,语义也不会允许有多个实例存在,而java规范规定类的构造必须是原子非并发的所以连getIntance()方法也都不需要加同步synchronized,一切的一切都very prefect ,所以我个人也最推荐使用静态内部类的单例实现方法,当然如果有更好的方法欢迎大家拍砖
原文地址:http://blog.csdn.net/u014793936/article/details/45009789