设计模式之——单例模式
单例模式定义
单例模式确保一个类只有一个实例,并提供一个全局访问点,我们把自己的类设计成自己管理的一个单独的实例,同时避免其他类在自行产生实例,当你需要实例时,向类查询,他会返回单个实例,采用延迟实例化的方式穿件单件对资源敏感的对象特别重要。
Sigleton{
private static Singleton unique;
private SingleTon(){}
public static SingleTon getInstance(){
if(unique == null){
unique = new Singleton();
}
return ubique;
}
}多线程下的单例
在多线程的情况下,我们设计的单例模式可能会出现多个实例化的对象,这跟我们的设计的初衷并符合,原因在于,当多个线程在同时访问getInstance时会出现unique的判断出现误差,会有多个实例被实例化的风险,因此我们有以下几种处理方式。
1.将getInstance()方法变为同步方法,这是最简单的解决方式,通过增加synchronized关键字,我们迫使每个线程进入这个方法之前要先等候别的线程离开这个方法,也就是说两个线程不会同时进入方法。
public static synchronized Singleton getInstance(){
……….
}
然而,虽然这种方法最简单,但是会出现性能问题,而且它所产生的问题要比想象的还要严重,因为getInstance方法只有在第一次调用时才会需要同步,在之后的调用中同步完全无用的,换句话说,一旦使用了同步方法,在以后的所有调用中都是同步的,很明显,这是完全没有必要的。
2.如果单例对象总是要创建和使用,或者在创建和运行时方面的负担不是太繁重,你可以使用迫切创建对象的方式而不是延迟创建对象,直接在类结构中实例化出来,这样就避免了因同步而出现的问题。
private static Singleton unique = new Singleton();
3.用双重检查枷锁,在getInstance中减少使用同步,利用这种方式,首先检查实例是否已经创建了,如果未创建,才进行同步,这样一来只有第一次会同步。
private volatile static Singleton unique;
public static Singleton getInstance(){
if(unique == null){
synchronized(Singleton.class){
if(unique == null){
unique = new Singleton();
}
}
}
return unique;
}
若果性能是你关注的重点,那么,这种方式可以帮你大大减少getInstance的时间消耗。