设想形式(4)单例形式(解说+运用)

目次

  1. 单例形式

  2. 为何运用单例形式

  3. 单例形式现实运用

单例形式

这个设想形式应当算是我最早接触到一个,也是从那个时刻晓得有一种东西叫设想形式,看到这类代码组织,有种将好的东西经由过程某种优美的包装举行包装一样,似如虎添翼。

单例形式:单例形式中有一个单例类的组织,来保证体系中,该类只能够被实例化一个,经由过程这类体式格局掌握体系中实例的个数,同时易于外界接见。

为何运用单例形式

关于缓存,数据库衔接,收集要求行列等,资本斲丧比较大的,一般我们只是须要一个实例,来削减资本的斲丧。
为何不实用静态全局变量来举行掌握呢?
经由过程静态全局变量持有一个我们建立的实例,然后对这个实例举行一些操纵不也是能够保证单例吗?这类体式格局好像要比多出一个设想形式去转变类的组织轻易的多,然则我们却不会如许去做,缘由就是

  1. 当我们设置一个全局的变量在体系中,其会致使涌现定名空间污染征象,致使我们在一些援用的过程当中,涌现了将全局变量作为局部变量运用的状况,

  2. 同时假如我们关于静态全局变量假如不加锁的话,很轻易在多线程操纵的过程当中带来同步上的一些题目,

  3. 末了一个缘由就是假如我们将其作为一个静态全局变量运用,那末我们就没法完成一个惰性建立实例,关于过于斲丧资本的实例,经由过程惰性建立,我们将其拖延至运用时建立,而不会过早的斲丧资本。

单例形式的现实运用

到了看一下单例形式庐山真面目标时刻了,起首经由过程一段简朴的Java代码看一下其大致组织。

public class Singleton{
    private static Singleton mSingleton = null;
    private Singleton(){

    }
    public static Singleton getInstance(){
        if(mSingleton==null)
            mSingleton = new Singleton();
        return mSingleton;
    }
}

上面是一个简朴单例形式的树模代码,经由过程这个代码,我们能够看出单例类的组织要领是私有要领,也就是该类我们没有办法经由过程new获得的,只能够经由过程静态的getInstance()要领获得。然则关于多线程题目,假如有多个线程在实行这个要领,那末能够就会有多个实例被建立出来,怎样应对这个题目呢?

1.对该代码地区举行同步

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

当我们对代码块举行加锁以后,一个线程就要比及另一个线程完毕以后,才能够继承实行该地区代码,然则当我们对一个代码地区举行加锁以后,我们的代码效力就会下降100倍。对这个代码地区举行同步以后,每当我们实行这块代码,都将会涌现一个守候。
2.迫切建立实例,而不是采纳惰性建立

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

    }
    public synchronized Singleton static getInstance(){
        return mSingleton;
    }
}

经由过程迫切建立在对类举行初始化的时刻就实例化了类,就不会涌现多个线程合作的题目,然则会致使的题目是假如建立实例斲丧过大的时刻就会涌现提早斲丧资本的题目。因而我们常采纳的一种要领是两重加锁法。
3.两重搜检加锁

public class Singleton{
    private static Singleton mSingleton = null;
    private Singleton(){

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

这类体式格局关于加锁不是对全部要领举行加锁,而是推断当这个单例未被初始化以后,才对这个实例的初始化地区举行一个同步,在同步的过程当中在举行一个是不是实例化的推断。即所谓的两重搜检。课有疑问的在于,我们已进入了同步地区了,为何还要对其做一个推断呢?就是当两个线程同时越过了第一个推断以后,假如我们在同步要领中没有对与实例的推断,这个时刻,我们就有能够涌现实例被建立两次的状况。
综上所述:综合效力,资本斲丧等来看,经由过程两重搜检加锁的体式格局来建立最为轻易。
单例形式在android中有那些运用呢?
android中有许多体系级别的全局变量,如时候,输入法,账户,状态栏等等
InputMethodManager类,CalendarDatabaseHelper类、Editable类等等。在这些类中,都存在一个要领getInstance,在该要领或直接返回对象的援用或推断一个类的援用是不是为NULL,若不为NULL,则直接返回该援用,若为NULL,则new一个新的对象,并返回。比方,关于CalendarDatabaseHelper类,存在以下的代码:

public static synchronized CalendarDatabaseHelper getInstance(Contextcontext)  
{  
    if (sSingleton == null)  
    {  
       sSingleton = newCalendarDatabaseHelper(context);  
    }  
        return sSingleton;  
}  

下一篇文章将更新关于装潢器设想形式相干的

    原文作者:Jensen
    原文地址: https://segmentfault.com/a/1190000003793726
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞