美文网首页Android开发Android开发Android架构之路
Android中的设计模式—单例模式

Android中的设计模式—单例模式

作者: BryanYue | 来源:发表于2018-07-01 02:42 被阅读14次

单例模式介绍

单例模式是应用最广的模式之一,也可能是很多人唯一会使用的设计模式。在应用单例模式时,单例对象的类必须保证只用一个实例存在。许多时候整个系统只需要一个全局对象,这样有利于我么能协调整个系统整体的行为。

单例模式的使用场景

确保某个类有且只有一个对象的场景,避免创建多个对象消耗过多的资源,或者某个对象只应该有且只有一个。例如,创建一个对象需要消耗的资源过多,如要访问IO和数据库的资源,需要频繁进行创建和销毁的对象,这时候就需要考虑使用单例模式。

单例的实现方式

饿汉式

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

    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

懒汉式

 public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

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

getInstance()方法中添加了synchronized关键字,也就是getInstance是一个同步方法,在多线程情况下保证单例的对象唯一性的手段。但是会发现个问题即使instance已经被初始化,每次调用getInstance方法都会进行同步,这样会消耗不必要的资源,这也是懒汉式的最大的文问题。最后总结下:
优点:单例只在使用时才被初始化,一定程度上节约了资源。
缺点:第一次加载时需要进行实例化,反应稍慢,最大问题是每次调用getInstance都会进行同步,造成不必要的同步开销,这种模式一般不建议使用

Double Check Lock(DCL)实现单例

public class Singleton {
    private static Singleton instance = null;

    private Singleton() {
    }

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

getInstance方法中对instance进行了两次判空,第一层判断主要是避免不必要的同步,第二层判断是为了在null放的情况下创建实例。由于Java编译器允许处理器乱序执行,在JDK1.5之前JMM(Java内存模型)会偶尔失败,会发生DCL失效问题。JDK1.5之后,SUN调整了JVM,又优化了volatile关键字,只要将instance定义改成 private volatile static Singleton instance = null就可以保证每次都是从主内存读取,就可以使用DCL的写法来完成单例。
优点资源利用率高,既能在需要时才初始化单例,又能保证线程安全,且单例对象初始化后调用getInstance不进行同步,效率高。
缺点第一次加载反应稍慢,也由于JMM的原因偶尔会失败。在高并发环境下也有一定缺陷,虽然发生的概率较小。
DCL模式是使用最多的单例模式实现方式,除非代码在并发场景比较复杂或者JDK1.6以下版本使用,否则,这种方式基本都能满足需求。

静态内部类单例模式

public class Singleton {
    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }

    private static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }
}

DCL模式虽然在一定程度解决了资源消耗、多余的同步、线程安全等问题,但是,它还是在某种情况下会出现失效问题。
第一次加载Singleton类并不会初始化instance,只有在第一次调用getInstance()方法时instance才被初始化,因此第一次调用getInstance方法会导致虚拟机加载SingletonHolder类,这种方法不仅能保证线程安全,也能保证单例对象的唯一性,同时也延迟了单例的实例化,所以这是推荐使用的单例模式。

枚举单例

public enum SingletonEnum {
    INSTANCE;
    public void doSomething() {
        System.out.println("do something");
    }
}

优点:简单
枚举在java中与普通类一样,不仅能有字段,还能够有自己的方法。重要的是枚举实例的创建是线程安全的,并且在任何情况下它都是一个单例。

容器实现单例

public class SingletonManager {
    private static Map<String, Object> objMap = new HashMap<String, Object>();

    public static void regsiterService(String key, Object instance) {
        if (!objMap.containsKey(key)) {
            objMap.put(key, instance);
        }
    }

    public static Object getService(String key) {
        return objMap.get(key);
    }
}

将多种单例注入一个统一的管理类,使用时根据key获取对象对应类型的对象。
这种方法是使得我们可以管理多种类型的单例,在使用过程中可以通过统一的接口进行操作,降低了使用成本,也对用户应藏了具体实现,降低了耦合。

总结

单例是运用频率很高的模式,因为客户端没有高并发的情况,选择哪种方式并不会有太大的影响,出于效率考虑,推荐使用DCL和静态内部类实现单例模式。
单例的优点

  1. 由于单例模式只存在一个实例,减少了内存开销,特别是一个对象需要频繁的创建、销毁时,而且创建或销毁时性能无法优化,单例模式的优势就十分明显。
  2. 由于单例模式只生成一个实例,减少了系统的性能开销,当一个对象的产生需要比较多的资源时,可以通过应用启动时直接产生一个单例对象。然后用永久驻留内存的方式来解决。
  3. 单例模式可以避免对资源的多重占用,比如文件的读写操作。
  4. 单例模式可以在系统中设置安全的访问点,优化和共享资源访问,比如可以设计一个单例类,负责所有数据表的映射处理。
    单例的缺点
  5. 单例模式一般没有接口,扩展困难。
  6. 单例对象如果持有Context,容易引发内存泄漏,此时需要传递给单例对象的Context最好是Application Context。

微信公众号:码农修炼之道

码农修炼之道

相关文章

  • Android 设计模式之简单工厂模式

    设计模式系列文章 Android 设计模式之单例模式 Android 设计模式之Builder模式 Android...

  • python中OOP的单例

    目录 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 单例

    目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • Android 架构师之路5 设计模式之单例模式

    Android 架构师之路 目录 前言 Java中单例(Singleton)模式是一种广泛使用的设计模式。单例模式...

  • Android 中的单例模式

    Android 中的单例模式 概述 单例模式算是我接触设计模式这种思想所学习的第一个设计模式。记得刚入行时面试,面...

  • 设计模式 - 单例模式

    设计模式 - 单例模式 什么是单例模式 单例模式属于创建型模式,是设计模式中比较简单的模式。在单例模式中,单一的类...

  • 简单聊聊单例模式

    单例模式应该是Android开发中常用的一种设计模式。不仅我们经常用到,Android源码中也经常可以看到单例模式...

  • python 单例

    仅用学习参考 目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计...

  • Android设计模式-模版方法模式

    UML关系简单介绍UML简单使用的介绍创建型设计模式Android设计模式-单例模式Android设计模式-工厂模...

  • Android设计模式-迭代器模式

    UML关系简单介绍UML简单使用的介绍创建型设计模式Android设计模式-单例模式Android设计模式-工厂模...

网友评论

    本文标题:Android中的设计模式—单例模式

    本文链接:https://www.haomeiwen.com/subject/aoaxuftx.html