转载请注明出处:http://blog.csdn.net/woshizisezise/article/details/50358924
单例模式是运用频率很高的模式,但是,由于在客户端通常没有高并发的情况,因此,选择哪种实现方式并不会有太大的影响。即便如此,出于效率考虑,我们推荐使用以下两种方式的实现形式。
1.Double Check Lock(DCL)实现单例
DCL方式实现单例模式的优点是既能够在需要时才初始化单例,又能保证线程安全,且单例对象初始化后调用getInstance不进行同步锁,代码如下所示:
public class Singleton{
private static Singleton sInstance = null;
private Singleton(){
}
public void doSomething(){
//这是你的业务代码
}
public static Singleton getInstance(){
if(sInstance == null){
synchronized (Singleton.class){
if(sInstance == null){
sInstance = new Singleton();
}
}
}
return sInstance;
}
2.静态内部类单例模式
DCL虽然在一定程度上解决了资源消耗、多余的同步、线程安全等问题,但是,它还是在某些情况下出现失效问题。这个问题被称为双重检查锁定(DCL)失效,在《Java并发编程实践》一书的最后谈到了这个问题,并指出这种“优化”是丑陋的,不赞成使用。而建议使用如下的代码代替:
public class Singleton{
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
/**
*静态内部类
*/
private static class SingletonHolder{
private static final Singleton sInstance = new Singleton();
}
}
当第一次 加载Singleton类时并不会初始化sInstance,只有在第一次调用Singleton的getInstance方法时才会导致sInstance被初始化。因此,第一次调用getInstance方法会导致虚拟机加载SingletonHolder类,这种方式不仅能够确保线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化,所以这才是推荐使用的单例模式实现方式。
优点:
(1)由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁地创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显。
(2)由于单例模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要比较多的资源时,比如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决。
(3)单例模式可以避免对资源的多重占用,例如一个写文件操作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
(4)单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如,可以设计一个单例类,负责所有数据表的映射处理。
缺点:
(1)单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。
(2)单例对象如果持有Context,那么很容易引发内存泄露,此时需要注意传给单例对象的Context最好是Application Context。
希望大家关注我更多的博客,我会不定期更新更多的内容,欢迎大家订阅公众号,我会不定期更新资源,供大家一起学习。