单例模式

开发中我们知道,我们能够使用一个全局变量让一个对象能够被访问,但它不能防止实例化多个对象。一个最好的办法就是让类自身负责保存它的唯一实例,这个类应该保证没有其他实例可以被创建,并且它应该提供一个访问该实例的方法。单例模式就是这样一种保证类对应仅有一个实例,并提供访问它的统一全局访问点的设计模式。

以Java语言为例,单例模式最简单的实现方法就是将构造函数设置为private访问权限,这样用户就不能new该对象了,用户只能通过我们提供的getInstance()方法初始化对象,方法内部会根据单例模式的要求按需new出对象。

实现单例模式

懒汉式单例模式

用户获取时初始化全局唯一的实例,这种单例模式称为懒汉式。

public class Student {
    private static Student student;

    private Student() {
        Student.student = new Student();
    }

    public Student getInstance() {
        return student;
    }
}

饿汉式单例模式

程序刚运行时实例就立即生成产生,这种单例模式称为饿汉式。

public class Student {
    private static Student student = new Student();

    private Student() {
    }

    public Student getInstance() {
        return student;
    }
}

注意单例模式的线程安全问题

以上述代码为例,我们先不考虑用户获取student实例后多线程操作它是否有问题,仅仅观察单例模式的两种实现,它是否仍有线程安全问题?

实际上,上面代码的懒汉式仍就不是线程安全的,因为多个线程同时调用getInstance()时可能造成创建多个student实例,这可能造成一些混乱!因此多线程情况下,懒汉式的单例模式应该使用线程同步,而饿汉式单例模式不存在这个问题。

何时使用哪种单例模式

懒汉式的实例按需加载但是可能造成线程安全问题,这种方式启动快,但是首次调用getInstance()方法时慢。饿汉式的实例程序启动时就加载,实现上不会有线程安全问题,但启动可能较慢。具体使用哪一种,应该根据程序的需求来选择合适的实现。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap