Android 单例模式的四种实现方式

一.饿汉式

public class SingletionStarving {

    private static final SingletionStarving mInstance = new SingletionStarving();

    private SingletionStarving() {

    }

    public static SingletionStarving getInstance() {
        return mInstance;
    }
}
  • 构造函数用private修饰,外部无法访问
  • 声明静态对象时就初始化
  • static关键字修饰,静态变量,存储在内存中,只有一份数据。
  • final关键字,只初始化一次,所以mInstance实例只有一个。

二.懒汉式

public class SingletionSlacker {

    private static SingletionSlacker mInstance;

    private  SingletionSlacker() {}

    public static synchronized SingletionSlacker getInstance() {
        if (mInstance == null) {
            mInstance = new SingletionSlacker();
        }
        return mInstance;
    }
}
  • 构造函数用private修饰,外部无法访问
  • 使用的时候即调用getInstance的时候才初始化
  • static关键字修饰,静态变量,存储在内存中,只有一份数据。
  • synchronized线程安全,多线程情况下单例的唯一性
  • 缺点:没次调用getInstance都会同步一次,浪费资源

三.双重检查加锁方式

网上建议和使用最多的方法

public class Singletion {

    private static Singletion mInstance;

    private Singletion() {}

    public static Singletion getmInstance() {
        if (mInstance == null) {
            synchronized (Singletion.class) {                if (mInstance == null) {
                    mInstance = new Singletion ();                }
            }
        }
        return mInstance;
    }
}
  • 构造函数用private修饰,外部无法访问
  • 使用的时候即调用getInstance的时候才初始化
  • static关键字修饰,静态变量,存储在内存中,只有一份数据
  • synchronized线程安全,多线程情况下单例的唯一性
  • 两次判断空,避免多次同步(synchronized)

缺点

private static Singletion mInstance;
private Singletion() {}
public static Singletion getmInstance() {}

由于jvm特性,允许乱序执行,上面三句代码顺序不定,那么就可能出现失效的问题。
步骤一、倘若A线程执行getmInstance(),还没执行构造方法Singletion()
步骤二、此时B线程调用getmInstance()。因为A已经执行getmInstance(),所以mInstance不为空就直接获取。
步骤三、由于B直接获取,而真实情况是A线程构造方法还未执行,所以mInstance就为空了。
虽然此情况发生概率较小,但也是一种情况。为了解决这种情况,java1.6开始加入volatile关键字

private volatile static Singletion mInstance;

这样就避免了方式失效的情况。虽然会volatile消耗一些性能,所以最佳写法

public class Singletion {

    private volatile static Singletion mInstance;
    private Singletion () {}
    public static Singletion getmInstance() {        if (mInstance == null) {
            synchronized (Singletion.class) {                if (mInstance == null) {
                    mInstance = new Singletion();                }
            }
        }
        return mInstance;
    }
}

虽然volatile让方式完美,但是没有volatile关键字的写法基本能满足绝大部分情况。除非你要运行在高并发,或者java1.6之前的代码中。

四.静态内部类方式

public class SingletionInternalClass {

    private SingletionInternalClass() {}

    public static SingletionInternalClass getInstance() {
        return SingletionInternalClassHolder.instance;
    }

    private static class SingletionInternalClassHolder {
        private static final SingletionInternalClass instance = new SingletionInternalClass();
    }
}

构造函数用private修饰,外部无法访问

使用的时候即调用getInstance的时候才初始化

调用getInstance才回去加载SingletionInternalClassHolder类,确保了线程安全,保证了单例的唯一性

总结

单例模式不管用那种方式实现,核心思想都相同
1、构造函数私有化,通过一次静态方法获取一个唯一实例
2、线程安全

最后推荐使用文中**双重锁方式和静态内部类的方式**来创建单例模式。

以上就是Android 单例模式的四种实现方式的详细内容,更多关于Android 单例模式的实现的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android中单例模式的一些坑小结

    前言 单例模式最初的定义出现于<设计模式>(艾迪生维斯理, 1994):"保证一个类仅有一个实例,并提供一个访问它的全局访问点." 而我对单例的理解是,在可控的范围内充当全局变量的作用,就相当于C语言中一个全局结构体. 首先来看这样一个单例,稍微有点经验的同学可能都会说,这样的单例是非线程安全的.要加个volatile关键字才可以. class Singleton{ private static Singleton singleton; private Singleton(

  • Android设计模式系列之单例模式

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

  • Android单例模式的几种方法总结

     Android单例模式的几种方法总结 因为单例模式过于简单,下面我就直接上代码了. 简单式: public class Single{ private static Single single=new Single(); public static Single instance(){ return singlel; } } 复杂式: public class Single{ private static Single single: public static Single instance

  • Android源码学习之单例模式应用及优点介绍

    单例模式定义: Ensure a class has only one instance, and provide a global point of access to it. 动态确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 如上图所示(截取自<Head First Design Patterns>一书). 通过使用private的构造函数确保了在一个应用中产生一个实例,并且是自行实例化(在Singleton中自己使用new Singleton()). 具体单例模式有

  • Android设计模式之单例模式解析

    在日常开发过程中时常需要用到设计模式,但是设计模式有23种,如何将这些设计模式了然于胸并且能在实际开发过程中应用得得心应手呢?和我一起跟着<Android源码设计模式解析与实战>一书边学边应用吧! 今天我们要讲的是单例模式 定义 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例 使用场景 确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源 某个类型的对象只应该有一个 使用例子 应用的Application 图片加载框架对象,比如我们的ImageLoader,常用的

  • Android开发中的单例模式应用详解

    本文实例讲述了Android开发中的单例模式应用.分享给大家供大家参考,具体如下: 单例模式是应用最广的设计模式之一,在应用这种模式的时候,单例对象的类必须保证只有一个实例存在.许多时候,整个系统只需要拥有一个全局对象,这样有利于协调系统的整体行为.如一个应用中,应该只有ImageLoader实例,这个ImageLoader实例中又包含网络请求.缓存系统.线程池等,很耗资源,因此没有理由让他构造多个实例.这种不能自由构造对象的情况就是使用单例模式的场景.在Android系统中存在很多这种场景,比

  • Android 单例模式 Singleton 简单实例设计模式解析

    单例模式 Singleton 简单实例设计模式解析 前言 今天我来全面总结一下Android开发中最常用的设计模式 - 单例模式. 关于设计模式的介绍,可以看下我之前写的:1分钟全面了解"设计模式" 目录 1. 引入 1.1 解决的是什么问题 之前说过,设计模式 = 某类特定问题的解决方案,那么单例模式是解决什么问题的解决方案呢? 含义:单例 =一个实例: 解决的问题:降低对象之间的耦合度 解决方法:单例模式,即实现一个类只有一个实例化对象,并提供一个全局访问点 1.2 实例引入 接下

  • android开发设计模式之——单例模式详解

    单例模式是设计模式中最常见也最简单的一种设计模式,保证了在程序中只有一个实例存在并且能全局的访问到.比如在Android实际APP 开发中用到的 账号信息对象管理, 数据库对象(SQLiteOpenHelper)等都会用到单例模式.下面针对一些例子分析一下我们在开发过程中应用单例模式需要注意的点.  一.作用 单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点 二.适用场景 1. 应用中某个实例对象需要频繁的被访问. 2. 应用中每次启动只会存在一个实例.如账号

  • Android编程设计模式之单例模式实例详解

    本文实例讲述了Android编程设计模式之单例模式.分享给大家供大家参考,具体如下: 一.介绍 单例模式是应用最广的模式之一,也可能是很多初级工程师唯一会使用的设计模式.在应用这个模式时,单例对象的类必须保证只有一个实例存在.许多时候整个系统只需要拥有一个全局对象,这样有利于我们协调系统整体的行为. 二.定义 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 三.使用场景 确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个.例

  • android设计模式之单例模式详解

    这是我们最常见的一类模式,对这一类模式有一个通用的特点就是: 封装创建的方式和过程. 这里所谓封装就是隐藏的意思,对对象的创建方法和过程不可见,或者是虚拟的过程. 隐藏创建方式,就是如单例,工厂方法,隐藏创建过程则是指builder,原型,至于抽象工厂,我认为他包含了以上两种. 我们想想一个对象的创建有哪些步骤? 1.创建什么东西?--接口定义 2.谁创建?        --决策类or帮助类 3.如何创建?     --how,创建过程 4.什么时候创建?    --创建时机的触发 由此可知,

  • 如何在Android studio 中使用单例模式

    本篇简单介绍如何在Android studio中 使用单例模式和使用注意事项. 单例模式 为什么要使用单例模式? 有一些对象我们只需要一个,只需要一个线程池 .缓存或是只有一台打印机.机器人 .机器人上面只有一个寻磁传感器.我们可以通过全局的静态变量来实现,但是全局变量在程序一开始就创建 可能比较耗费资源.可能一直没用到.单例模式和全局变量一样方便又没有它的缺点. 单利模式使用 public class Sensor { // 使用静态变量记录唯一的实例 private static Senso

随机推荐