单件模式确保一个类只有一个实例,并提供一个全局访问点。

  作用:有一些常用来管理资源的对象(如线程池,数据库连接。。。)我们只需要一个,而事实上,这类对象这只能有一个,如果制造出多个实例,就会导致许多问题,比如,程序的行为异常,资源使用过量,或者是不一致的结果。

  关键点:私有构造器,静态变量,静态方法

  下面用一个例子来具体说一下:  

public class Hachun
{
    // 利用一个静态变量来记录Hachun类的唯一实例
    private static Hachun UniqueInstance;
 
    // 私有构造器,只有在Hachun类内才能调用构造器(即实例化该对象),防止其他地方随意创建
    private Hachun(){}  

    // 此静态方法用来实例化Hachun对象,并返回这个实例,外部类可以通过该方法获得Hachun对象
    public static Hachun getInstance()
    {
         // 只有当UniqueInstance为null时,才实例化,确保该对象只有一个
        if (UniqueInstance==null)     
        {
            UniqueInstance = new Hachun();
        }

        return UniqueInstance;
    }
}

  但这样可能会出现多线程的问题,从而导致异常,下面介绍一个处理该问题的方法:

  修改getInstance()方法

public static synchronized Hachun getInstance()
{
    if (UniqueInstance==null)     
    {
        UniqueInstance = new Hachun();
    }

    return UniqueInstance;
}

通过添加关键字 synchronized,将迫使每个线程在进入这个方法之前,要先等候别的线程离开该方法,也就是说,不会有两个线程同时进入这个方法,但,这个方法,会降低性能。

  再看看另一个方法,急切实例化:  

public class Hachun
{
    // 保证线程安全
    private static Hachun UniqueInstance = new Hachun();   

    private Hachun(){} 

    public static Hachun getInstance()
    {
        return UniqueInstance;
    }
}

如果应用程序总是创建并使用这个单件实例,或者在创建和运行时方面的负担不是太繁重,上述方法比较适合。

  如果你比较关心性能,试试 双重检查加锁(两个 if 检查判断) 方法:  

public class Hachun
{
    // volatile关键字确保 当UniqueInstance变量被初始化成 Hachun 实例时, 多个线程正确地处理UniqueInstance变量
    private volatile static Hachun UniqueInstance;  

    private Hachun(){} 

    public static Hachun getInstance()
    {
        if (UniqueInstance==null)     
        {
            //  同步区块,UniqueInstance若为null,则创建
            synchronized(Hachun.class)    
            {
                if (UniqueInstance==null)
                {
                    UniqueInstance = new Hachun();
                }
            }
        }

        return UniqueInstance;
    }
}

 

 

 

 

 

 

 

 

 

posted on 2013-12-08 21:43  花爱春  阅读(239)  评论(0编辑  收藏  举报