前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >羊皮书APP(Android版)开发系列(二十二)10分钟秒懂单例模式

羊皮书APP(Android版)开发系列(二十二)10分钟秒懂单例模式

作者头像
热心的程序员
发布2018-08-30 10:36:50
2860
发布2018-08-30 10:36:50
举报
文章被收录于专栏:编程之路编程之路

单例模式在实际开发过程中经常会用到,我们有必要充分的理解单例模式。单例模式有多种写法,分为懒汉式、饿汉式、双重锁等。

单例模式的定义:
  • 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式的好处:
  1. 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;
  2. 由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。
饿汉式:
代码语言:javascript
复制
public class Singleton1 {
    //私有的默认构造子
    private Singleton() {}
    //已经自行实例化 
    private static final Singleton single = new Singleton();
    //静态工厂方法 
    public static Singleton getInstance() {
        return single;
    }
}
  • 当这个类被加载的时候,new Singleton() 这句话就会被执行,就算是getInstance()没有被调用,类也被初始化了。但是,我们希望他能在我第一次getInstance()时才被真正的创建。这样,我们可以控制真正的类创建的时刻,而不是把类的创建委托给了类装载器。
懒汉式(一):
代码语言:javascript
复制
public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}
  • 仅能用于单线程中,在多线程中不能正常工作。
懒汉式(二):
代码语言:javascript
复制
public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
} 
  • 可在多线程中很好的工作。
静态内部类:
代码语言:javascript
复制
public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE; 
    }  
}
  • 这种方式在《Effective Java》上推荐使用。这种写法仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了 getInstance() 之外没有办法访问它,因此它是懒汉式的;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖 JDK 版本。
双重校验锁:
代码语言:javascript
复制
public class Singleton {
    private volatile static Singleton singleton;

    private Singleton() {
    }

    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
} 
  • volatile 禁止指令重排序优化。也就是说,在 volatile 变量的赋值操作后面会有一个内存屏障(生成的汇编代码上),读操作不会被重排序到内存屏障之前。只能用于JDK 1.5及以上,在JDK1.5以前不能使用。
总结:
  1. 《懒汉式(二)》很常见,但是一般会偏向使用《静态内部类》的方式。
  2. 《双重校验锁》方式也很好,但是它会受到JDK的约束,如果在JDK 1.5及以上使用完全没有问题。
  3. 在Android开发中,在开源框架Android-Universal-Image-Loader的ImageLoader中就是使用《双重校验锁》的方式,所以在Android开发中,我们可以直接使用《双重校验锁》的方式。
  4. Android开发中,单例模式常会用于我们的对业务的封装类中,如:对网络请求的封装、图片加载的封装等。

单例模式使用的一个实际例子见下一篇

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.04.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单例模式的定义:
  • 单例模式的好处:
  • 饿汉式:
  • 懒汉式(一):
  • 懒汉式(二):
  • 静态内部类:
  • 双重校验锁:
  • 总结:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档