Android设计模式之单例模式(Singleton Pattern)

个人总结学习和研究,部分内容参考《Android源码设计模式解析与实战》一书~~

一.  定义: 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

也就是说,单例要满足3点:

1、单例类只能有一个实例。

2、单例类必须自己创建自己的唯一实例。(构造函数私有化,防止外部程序通过new来构造)。

3、单例类必须给其他对象提供这一实例。(暴露公有静态方法或者通过枚举返回单例类对象)。

二.  使用场景: 确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源。比如说在一个应用中,应该只有一个ImageLoader实例,这个Imageloader中含有线程池、缓存系统、网络请求等,比较消耗资源。还比如访问IO和数据库等资源,就要考虑使用单例模式。

android源码中也有很多地方用了单例模式,比如说输入法管理者InputMethodManager,比如一个应用只有一个Application对象等。

三. 实现方式:

1、饿汉式单例

特点:声明静态对象的时候进行初始化静态对象,以后不再改变,天生是线程安全的。弊端:消耗资源。

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

2、懒汉式单例

特点:声明静态对象,并在第一次调用getInstance时进行初始化。优势:延迟加载。弊端:线程不安全。

public class Singleton {

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

懒汉式加锁

getInstance()静态方法添加synchronized关键字,即同步方法保证线程安全。  弊端:造成不必要的同步开销。具体代码如下:

public class Singleton {

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

3、双重检查锁定(Double CheckLock)实现单例

特点:延迟加载,解决了多余的同步,线程安全。

两次判空,第一层是为了避免不必要的同步。 第二层是为了在instance为null的情况下创建实例。

 

public class Singleton {

    private static Singleton instance = null;

    private Singleton {
    }

    public static Singleton getInstance () {
        // If already initialized, no need to get lock everytime.
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance ;
    }
}

  

4、静态内部类单例

特点:延迟加载,线程安全。  利用Java虚拟机加载类的特性实现延迟加载和线程安全, 推荐使用的单例实现方式。

public class Singleton() {
    private Singleton() {
    }

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

    /**
     * 静态内部类,只有在装载该内部类时才会去创建单例对象
     */
    private static class SingletonHolder {
         private static final Singleton instance = new Singleton();
    }
}

5、枚举单例

特点:写法简单,线程简单,反序列化也不会重新创建对象。(前面四种情况在反序列化中均会生成新的实例)。

枚举单例虽然在Effective Java中推荐使用,但是在Android平台上却是不被推荐的。

Android官方的Training课程中明确指出:

Enums ofter require more than twice as much memory as static constants. You should strictly avoid using enums on Android.

public enum Singleton {
    // 定义一个枚举的元素,它就是Singleton的一个实例
    INSTANCE;
    public void doSomethig() {
        // TODO:
    }
}

枚举在java中与普通的类一样的,不仅能够有字段,还能够有自己的方法。

最重要的是默认枚举实例的创建是线程安全的,并且在任何情况下都是一个单例。  使用方法如下:

Singleton singleton = Singleton.INSTANCE;
singleton.doSomething();

6、使用容器实现单例

脑洞打开,再来看看一种另类的实现方式。维护一个统一的管理类,注入多种单例类型,在使用时根据key获取对应类型的单例对象。

public class SingletonManager {

    private static Map<String, Object> objMap = new HashMap<>();
    private Singleton() {
    }

    public static void addSingleton(String key, Object instance) {
        if (!objMap.containsKey(key)) {
            objMap.put(key, instance);
        }
    }
    public static getSingleton(String key) {
        return objMap.get(key);
    }
}

  

总结:  选择哪种实现方式取决于项目本身,如是否是复杂的并发环境、JDK版本是否过低,单例对象的资源消耗等。一般而言,客户端通常没有高并发的情况,所以具体选择哪种实现方式并不会有太大的影响。个人一般使用静态内部类的实现方式。

注意: 单例对象如果持有Context,很容易引发内存泄露,需要注意传递给单例对象的Context最好是Application Context。

时间: 04-03

Android设计模式之单例模式(Singleton Pattern)的相关文章

设计模式之单例模式Singleton pattern

单例模式Singleton pattern 一种软件设计模式.在核心结构中只包含一个被称为单例的特殊类. 一个类只有一个对象实例,并且自行实例化向整个系统提供. 动机 一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务:一个系统只能有一个窗口管理器或文件系统:一个系统只能有一个计时工具或ID(序号)生成器.如在Windows中就只能打开一个任务管理器.如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源:如果这些窗口显示的内容不

二十四种设计模式:单例模式(Singleton Pattern)

单例模式(Singleton Pattern) 介绍保证一个类仅有一个实例,并提供一个访问它的全局访问点. 示例保证一个类仅有一个实例. Singleton using System; using System.Collections.Generic; using System.Text; namespace Pattern.Singleton { /// <summary> /// 泛型实现单例模式 /// </summary> /// <typeparam name=&q

Android设计模式之单例模式 Singleton

一.概述 单例模式是设计模式中最简单的一种,但是它没有设计模式中的那种各种对象之间的抽象关系,所以有人不认为它是一种模式,而是一种实现技巧.单例模式就像字面的意思一样,提供一个只能自己实例化的实例,并且提供了一个全局的访问点.要达到这几点要求就要满足三点:私有构造函数(防止被别人实例化),静态私有自身对象(用来提供实例),静态公有的getInstance方法(用来创建和获取实例对象). 优缺点: 单例只允许自己建立一个实例,不需要频繁创建和销毁,可以节省内存加快对象的访问速度. 但是单例没有抽象

设计模式 - 单件模式(singleton pattern) 详解

单件模式(singleton pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/28595349 单件模式(singleton pattern) : 确保一个类只有一个实例, 并提供一个全局访问点. 单价模式包括3个部分: 私有构造器, 静态变量, 静态方法. 具体方法: 1. 标准的单例模式: /** * @time 2014.6.5 */ package singleton; /** * @author

(转)设计模式之——单例模式(Singleton)的常见应用场景

单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此有些设计大师并把把其称为设计模式之一. 这里又不具体讲如何实现单例模式和介绍其原理(因为这方便的已经有太多的好文章介绍了),如果对单例模式不了解的可以先看下:http://terrylee.cnblogs.com/archive/2005/12/09/293509.html .当然也可以自己搜索.

设计模式之单例模式——Singleton

                    设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有公开的调用方法.而且,别的类不能实例化它,所以构造方法要设置为私有的. 单例模式的要点 一是某个类只能有一个实例: 二是它必须自行创建这个实例: 三是它必须自行向整个系统提供这个实例. 例如: 有一个"单例对象",而"客户甲"."客户乙" 和&quo

ninject学习笔记二:单例模式singleton pattern

今天准备学习singleton pattern,顾单词思含义,就是一个实例的意思.单例的实现思路是:私有化构造函数,提供公有方法获取类的实例.下面定义一个音乐播放器类MusicPlayer,观察单例的实现方法 class MusicPlayer { private static readonly MusicPlayer player = new MusicPlayer(); private MusicPlayer() { } public static MusicPlayer GetInstan

java设计模式之单例模式(Singleton)

Java设计模式之单例模式 单例模式是什么? 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式如何来设计呢? 保证一个类只能有一个实例,那么我们不能无限制的new 来创建,因为我们知道,new一次就是一个新的对象,那么构造器只能私有化private -- 构造器私有化 构造器私有化了,问题又出现了,构造器私有化了,那么我们怎么来创建唯一的对象呢?-- 提供一个公有的方法/提供一个公有的静态属性 再分析一下,公有方法, 实例方法还是类方法呢?--公有的类方法(获取类实例) 依据以上

.NET设计模式实例之单例模式( Singleton Pattern)

一.单例模式简介(Brief Introduction) 单例模式(Singleton Pattern),保证一个类只有一个实例,并提供一个访问它的全局访问点.单例模式因为Singleton封装它的唯一实例,它就可以严格地控制客户怎样访问它以及何时访问它. 二.解决的问题(What To Solve) 当一个类只允许创建一个实例时,可以考虑使用单例模式. 三.单例模式分析(Analysis)1.单例模式结构 Singleton类,定义一个私有变量instance;私有构造方法Singleton(

Android设计模式系列-单例模式

单例模式,可以说是GOF的23种设计模式中最简单的一个. 这个模式相对于其他几个模式比较独立,它只负责控制自己的实例化数量单一(而不是考虑为用户产生什么样的实例),很有意思,是一个感觉上很干净的模式,本人很喜欢这个模式.android中很多地方都用到了单例模式,本文以输入法管理者InputMethodManager为例,展开分析.单例模式,Singleton Pattern,能够以其特有的优势,替代系统中全局变量,应用非常广泛. 1.意图保证一个类仅有一个实例,并提供一个访问它的全局访问点.热门