美文网首页程序员设计模式
设计模式:第五篇--单例模式

设计模式:第五篇--单例模式

作者: Jorgezhong | 来源:发表于2018-09-25 10:54 被阅读18次

单例模式:确保一个类只有一个实例,并提供要给全局访问点。
适用场景:共享的资源,比如数据库连接池,缓存等。我们可以尝试将需要释放资源的对象用单例模式管理起来,就想连接池和线程池那样。

延迟实例化+线程不安全

经典的单例模式采取了“延迟实例化”的方式。即当程序用到的时候才会创建他,没有用到就不创建了。

/**
 * Project <demo-project>
 * Created by jorgezhong on 2018/9/25 9:42.
 * <p>
 * 经典单例模式
 * - 利用静态成员变量记录单例对象
 * - 私有构造方法
 * - 提供静态方法获取成员变量
 */
public class Singleton {


    private static Singleton uniqueInstance;

    private Singleton() {
    }

    public static Singleton getInstance() {

        //延迟实例化
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }


}
非延迟实例化+线程安全

问题:出现多线程问题,多线程情况下,可能会实例化多个对象。
思考:可使用同步锁synchronized,这样会消耗性能,其实使用的时候,只有第一次实例化的时候才需要保持同步,之后便不需要了,因此如果加synchronized的话,每次调用方法都要加所,会消耗性能。那既然这样的话,不使用延迟的方式不久没有线程安全问题了吗?静态初始化的时候给成员变量赋值就好了。

/**
 * Project <demo-project>
 * Created by jorgezhong on 2018/9/25 10:28.
 * <p>
 * 静态初始化的时候:初始化单例对象,解决线程安全问题
 */
public class Singleton {

    private static Singleton uniqueSingleton = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstacne() {

        return uniqueSingleton;
    }

}
延迟实例化+线程安全

问题:那如果我非得要使用延迟实例化的方式呢?有时候由于实例化对象太大,而且程序运行中很多时候并不会用到。所以想要使用延迟实例化的方式。
思考:那么还得使用synchronized的方式呀。不过,需要加上双重判断,这样只需要在实例化完成之前执行锁代码就可以了,如果在成员变量中加上volatile修饰就更好了。

/**
 * Project <demo-project>
 * Created by jorgezhong on 2018/9/25 10:41.
 *
 * 双重检查
 */
public class Singleton {

    //volatile:确保可见性,保证每个线程拿到的值是最新的
    private volatile static Singleton uniqueSingleton;

    private Singleton() {
    }

    public static Singleton getInstance() {

        //第一次检查,进入锁代码
        if (uniqueSingleton == null) {
            synchronized (Singleton.class) {
                //第二次锁内检查,确保线程安全
                if (uniqueSingleton == null) {
                    uniqueSingleton = new Singleton();
                }
            }
        }

        return uniqueSingleton;

    }

}
总结:

单例模式比较简单,使用场景也时比较常见的,有时候我们会引入一些工具像nosql这些,经常需要去获取连接,管理这些连接的对象可以时使用单例的,这样我们就不需要为资源未释放而烦恼。缓存控制和日志对象也是可以使用的。

相关文章

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • python中OOP的单例

    目录 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 单例

    目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 设计模式 - 单例模式

    设计模式 - 单例模式 什么是单例模式 单例模式属于创建型模式,是设计模式中比较简单的模式。在单例模式中,单一的类...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • python 单例

    仅用学习参考 目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计...

  • 基础设计模式:单例模式+工厂模式+注册树模式

    基础设计模式:单例模式+工厂模式+注册树模式 单例模式: 通过提供自身共享实例的访问,单例设计模式用于限制特定对象...

  • 单例模式

    JAVA设计模式之单例模式 十种常用的设计模式 概念: java中单例模式是一种常见的设计模式,单例模式的写法...

  • 设计模式之单例模式

    单例设计模式全解析 在学习设计模式时,单例设计模式应该是学习的第一个设计模式,单例设计模式也是“公认”最简单的设计...

网友评论

    本文标题:设计模式:第五篇--单例模式

    本文链接:https://www.haomeiwen.com/subject/oqykoftx.html