单例模式
开发中我们知道,我们能够使用一个全局变量让一个对象能够被访问,但它不能防止实例化多个对象。一个最好的办法就是让类自身负责保存它的唯一实例,这个类应该保证没有其他实例可以被创建,并且它应该提供一个访问该实例的方法。单例模式就是这样一种保证类对应仅有一个实例,并提供访问它的统一全局访问点的设计模式。
以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进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。