单例模式(Singletion)

单例模式(Singletion),我估计你们用到比较多.我使用的第一个设计模式就是单利模式.java

单例模式是为了确保一个类有且仅有一个实例,并为它提供一个全局访问点.简单说就是你不能new一个实例出来.设计模式


举一个例子,好比在个人开发中有这样一种状况,咱们有同事写了一组地图工具MapUtils.java,咱们在不一样的使用地方来调用这个工具类,为了不有多个工具类实例存在就使用单利模式.安全

1、懒汉单利模式模式并发

public class MapUtils {

    private MKSearch           mkSearch;
    private LocationClient     locationClient;
    private OnLocationListener listener;

    private static MapUtils    instance;

    private MapUtils() {
    }

    public static MapUtils getInstance(Context context) {
        if (null == instance) {
            instance = new MapUtils(context.getApplicationContext());
        }
        return instance;
    }
}

构造函数为private,这样就不能使用new来建立实例.惟一实例只能经过getInstance()方法访问。(事实上,经过Java反射机制是可以实例化构造方法为private的类的,那基本上会使全部的Java单例实现失效。此问题在此处不作讨论.)函数

上面的单例模式为懒汉单例模式,懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下极可能出现多个MapUtils实例,要实现线程安全,有如下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全,若是你第一次接触单例模式,对线程安全不是很了解,能够先跳过下面这三小条,去看饿汉式单例,等看完后面再回头考虑线程安全的问题.工具

一、在getInstance方法上加同步学习

public static synchronized MapUtils getInstance(Context context) {  
	if (null == instance) {    
	    instance = new MapUtils(context.getApplicationContext());
	}    
	return instance;  
}

二、双重检查锁定线程

public static MapUtils getInstance(Context context) {
    if (null == instance) {
        synchronized (MapUtils.class) {
            if (null == instance) {
                instance = new MapUtils(context.getApplicationContext());
            }
        }
    }
    return instance;
}

三、静态内部类设计

public class MapUtils {
    private static class LazyHolder {
        private static Context context;
        private static final MapUtils INSTANCE = new MapUtils(context.getApplicationContext());
    }
    private MapUtils(Context context){}
    public static final MapUtils getInstance(Context context) {
        LazyHolder.context = context;
        return LazyHolder.INSTANCE;
    }
}

2、饿汉式单例模式code

//饿汉式单例类.在类初始化时,已经自行实例化

public class MapUtils {  
    private MapUtils() {}  
    private static final MapUtils instance = new MapUtils();  
    //静态工厂方法   
    public static MapUtils getInstance() {  
        return instance;  
    }  
}

饿汉式在类建立的同时就已经建立好一个静态的对象供系统使用,之后再也不改变,因此天生是线程安全的。 还有一种登记式单例模式.没有细细去看就不作介绍了.


什么是线程安全? 若是你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。若是每次运行结果和单线程运行的结果是同样的,并且其余的变量的值也和预期的是同样的,就是线程安全的。 或者说:一个类或者程序所提供的接口对于线程来讲是原子操做,或者多个线程之间的切换不会致使该接口的执行结果存在二义性,也就是说咱们不用考虑同步的问题,那就是线程安全的。


PS:对于设计模式我只是做为学习笔记来写的,并不是网上大牛们的手笔,因此各位看官看看就行,有错误请多多指正,要真正学习设计模式,书籍有,《大话设计模式》,这个须要C++语言底子,《您的设计模式》这个讲解的颇有风趣,没有《大话设计模式》讲解的深,还有一本《Head First 设计模式》也讲解的蛮有意思的。

相关文章
相关标签/搜索