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

来源:互联网 发布:端口是什么 怎么查看 编辑:程序博客网 时间:2024/05/21 11:28

很长一段时间,根本区分不了各种设计模式。

工作过程中,经常用到单例模式,才算第一次了解一种设计模式


单例概念:确保某个类只有一个实例,并且自行实例化,并向整个系统提供该实例

为什么要使用单例模式呢?

记得开发工程中,打开相机页面这个ActiivtyCamera这个类,最初并没有被设计成单例模式,导致每次返回竟然返回2次才能关闭相机,创建了2个acitiviy页面,如果设计成单例模式就可避免该问题。

优点:

微笑由于单例模式在内存中只有一个实例,减少了内存开销。

哭单例模式可以避免对资源的多重占用,例如读、写文件操作

微笑单例模式可以在系统设置全局的访问点,优化和共享资源访问。

优点这么多,多的我也说不上来。。。。。


看了很多博客,说懒汉模式,或者饿汉模式都有缺点,那就看看双重检查锁定模式,直接上栗子。

    private static $class$ m$class$ = null;

    private $class$() {
    }

    public static $class$ getInstance() {
        if (m$class$ == null) {
            Synchronized($class$.class) {
                if (m$class$ == null) {
                    m$class$ = new $class$;
                }
            }
        }
        return m$class$;
    }


双重检查锁定模式:无非就是判空2次,并实现同步块,还有一种写法(volatile),对比一下:

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

2者区别仅在于volatile这个关键字,volative易变的。

构造函数私有,这个都知道,getInstance(),静态公有方法

volatile: 易变的,肯定是不容易确定的,这个就是告诉jvm 当前变量在寄存器中的值是不定的,需要从内存中读取,用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的值。

Synchronized:同步,同步代码块用该关键字实现,在多线程访问的时候,同一时刻只能有一个线程访问用Synchronized修饰的代码块或者方法。不但保证了可见性还保证了原子性。可见性原子性我也傻傻分不清楚,自行百度。

再就是这个双重判断null :
这是因为如果线程A进入了该代码,线程B 在等待,这是A线程创建完一个实例出来后,线程B 获得锁进入同步代码,实例已经存在,木有必要再创建一个,所以双重判断有必要。(这个解释我服气)InputMethodManager类就是单例模式。

双重锁定模式优于懒汉模式,饿汉模式也行现在你明白了吗?不明白的接着看:

懒汉模式:栗子

package com.example.mytry;public class Util {    private static Util instance;    private Util() {}    public static Util getInstance() {        if (instance == null) {            instance = new Util();        }        return instance;    }}

单例模式的懒汉式实现方式体现了延迟加载的思想。

什么是延迟加载呢?
        通俗点说,就是一开始不要加载资源或者数据,一直等,等到马上就要使用这个资源或者数据了,躲不过去了才加载,所以也称Lazy Load,不是懒惰啊,是“延迟加载”,这在实际开发中是一种很常见的思想,尽可能的节约资源。

哦,原来不是懒,是为了达到节约资源的目的。

那饿汉模式呢,怎么看怎么没差别啊?

package com.example.mytry;public class Util {    private static final Util instance = new Util();    private Util() {    }    public static Util getInstance() {        return instance;    }}

饿汉式 static final field

这种方法非常简单,因为单例的实例被声明成 static 和 final 变量了,在第一次加载类到内存中时就会初始化,所以创建实例本身是线程安全的。饿汉式的创建方式在一些场景中将无法使用。

http://blog.csdn.net/nsw911439370/article/details/50456231 此博客讲的比较详细,可参考!

1:时间和空间
        比较上面两种写法:懒汉式是典型的时间换空间,也就是每次获取实例都会进行判断,看是否需要创建实例,费判断的时间,当然,如果一直没有人使用的话,那就不会创建实例,节约内存空间。
        饿汉式是典型的空间换时间,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断了,节省了运行时间。

2: 线程安全
   从线程安全性上讲,不加同步的懒汉式是线程不安全的,比如说:有两个线程,一个是线程A,一个是线程B,它们同时调用getInstance方法,那就可能导致并发问题























阅读全文
0 0
原创粉丝点击