• 设计模式学习之单例模式


    最近在看设计模式,之前也断断续续了解了一些,但理解都不是很深,所以想系统的学习一下。
    刚开始就从简单的入手,很熟悉的单例模式:
    自己之前曾经这样用过:据说叫饿汉式,我想了半天不知饿汉是什么意思。Wikipedia给了一个名词叫Traditional simple way.我喜欢这个名字,简单好记,很形象。

    public class Singleton{
    private static final Singleton aInstance = new Singleton();
    public static Singleton getInstance(){
    return aInstance;
    }
    }


    当然,为了防止调用者私自new出Singleton,可以再加一个方法:

    private Singleton(){}

    JVM只会对静态初始化初始一次,所以这样写解决了单例的要求。由于这种写法在类加载的时候会立即对对象初始化,于是又有另一种推迟初始化的写法(懒汉式 Lazy initialization):

    public class Singleton{
    private static Singleton aInstance = null;
    public static Singleton getInstance(){
    if(aInstance == null){
    aInstance = new Singleton();
    }
    return aInstance;
    }
    }

    这样加载固然没有问题,但当对多线程的时候问题就来了。这个方法不是线程安全的。于是为了解决这个问题,我的第一个想法是加上synchronized关键字。没错ok,是一个解法,但当参考资料的时候,结果发现有大牛这样解决:

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

    这样解决了高并发量时的 synchronized 关键字降低效率的问题(synchronized 修饰的部分只会在第一次初始化的时候执行)
    使用 volatile 关键字是因为它具有 synchronized 可见的特点,线程会实时得知aInstance是否实例成功。保证了线程安全,被叫做Double-checked locking.
    但有人提示说volatile关键字可能会屏蔽掉虚拟机中一些必要的代码优化,所以运行效率并不是很高。没有特殊需要的情况下,这种方法也不一定能够提高效率。
    除了这种解决方案以外,还有没有其他的呢。答案是肯定的。有一种充分利用了static 初始化的特点的方法,叫做initialization on demand holder idiom.wikipedia上又叫(The solution of Bill Pugh)

    public class Singleton{
    private static class SingletonHolder {
    public static final Singleton aInstance = new Singleton();
    }
    public static Singleton getInstance(){
    return SingletonHolder.aInstance;
    }
    }

    看到这个解决方案不禁拍手叫妙,它既解决了懒惰初始化,又解决了线程安全。而且代码比之前用Double-checked locking看着舒服很多。

    由于笔者水平有限,难免会有出错之处,欢迎大家批评指正。
  • 相关阅读:
    Javascript高级篇-Function对象
    Object类、instanceof
    [一]Head First设计模式之【策略模式】(鸭子设计的优化历程)
    匿名内部类
    设计模式之单例模式
    长江商业评论读书笔记
    [转]Freemarker数据类型转换
    面向对象编程——概论(一)
    IP地址处理模块IPy
    系统性能模块psutil
  • 原文地址:https://www.cnblogs.com/sheling/p/pattern_singleton.html
Copyright © 2020-2023  润新知