单例模式(Singletion)

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

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


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

一、懒汉单利模式模式

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这个方法改造,保证了懒汉式单例的线程安全,如果你第一次接触单例模式,对线程安全不是很了解,可以先跳过下面这三小条,去看饿汉式单例,等看完后面再回头考虑线程安全的问题.

1、在getInstance方法上加同步

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

2、双重检查锁定

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

3、静态内部类

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;
    }
}  

二、饿汉式单例模式

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

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

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


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


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

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值