关于单例模式

《《仅供自己观看!!!》》

昨天刚刚看了一下关于单例模式的书《研磨设计模式》,很棒的一本书!

-----------------------------------朕是分割线-----------------------------------

关于单例模式,总体来说分为懒汉式和饿汉式,当然,饿汉式更加简单,比较单调。

public class Singleton    
{    
    private static final Singleton singleton = new Singleton();
   
    private Singleton()    
    {    
    }    
    public static Singleton getInstance()    
    {    
        return singleton;    
    }    
} 

这种就是简单的饿汉式的模板,最重要的思想就是控制了实例只能new一个,通过对构造函数的控制,不能随便new出实例,只能通过调用getInstance()方法得到实例,因为static是共享同一内存区域的。

懒汉式:

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

这种方法叫做double-check 双重检查,其中,被volatile修饰的变量的值将不会被本地线程缓存,所以对该变量的读写都是直接操作共享内存,从而使多线程正确处理该变量。如果你只使用第一个if()去判断实例是否已经存在,那么就可能在多线程情况下出现错误,还是可能导致多实例

public class Singleton    
{    
    private static final Singleton singleton = null;    
   
    private Singleton()    
    {    
    }    
    public static Singleton getInstance()    
    {    
        if (singleton== null)    
        {    
            singleton= new Singleton();   
        }    
        return singleton;    
    }    
} 

因为在多线程情况下,两个线程都进入if()中这是很有可能发生的,然后我们期望的单例就破灭啦!!!

所以还是用上面的double-check吧!

当然,在Java中还有一种更好的单例实现方式,既能实现延迟加载、又能实现线程安全!!!

肯定是有的,它利用的是Java中的静态初始化类,让JVM保证线程安全

public class Singleton    
{    
    private volatile static final Singleton singleton = null;    
   
    private Singleton()    
    {    
    }    
    /*
   *静态初始化器,由JVM保证线程安全
   */  
    private static class SingletonHolder{
        private static Singleton instance = new Singleton();
    } 
    public static Singleton getInstance()    
    {    
        return SingletonHolder.instance;    
    }    
}     

至于这里面后续的缓存和延迟加载,待续....

posted @ 2016-07-24 10:06  想名字头痛  阅读(296)  评论(0编辑  收藏  举报