单例模式(Singleton)是一种常见的设计模式,是指类的一个对象在系统中只有一个实例。
单例模式有很多应用场景
- Windows系统中的
任务管理器
和回收站
就是典型的单例模式,无论在什么位置打开,系统中始终只有一个任务管理器和回收站。 - 网站中的
计数器
一般也是采用单例模式,否则难以同步。 - 应用程序的
日志应用
,一般都使用单例模式实现,从而方便内容追加。
单例模式的三要素
- 私有的构造方法;
- 指向自己实例的私有静态引用;
- 以自己实例为返回值的静态的公有方法。
单例模式的作用
保证一个类只有一个实例,并且提供一个访问该实例的全局站点。
单例模式的实现
如果想要保证只有一个实例,就要保证外界不能随便new这一个对象,因此要将构造方法私有化
。
私有化构造方法即将new这个对象的权限收回,只能在这个类的内部去实例化这个对象。
单例模式的两种常见形式
“懒汉式”
"懒汉式"
顾名思义就是很懒的意思,只有在需要某个类的实例的时候才会执行,new出唯一的一个对象。
"懒汉式"示例
public class Singleton1 {
//定义一个变量来存储创建好的类实例
//因为这个变量要在静态方法中使用,所以需要加上static修饰
private static Singleton1 instance = null;
//私有化构造方法,好在内部控制创建实例的数目
private Singleton1() {
}
//定义一个方法来为客户端提供类实例
//这个方法需要定义成类方法,也就是要加static
public synchronized static Singleton1 getInstance() {
//判断这个实例是不是有值
if (instance == null) {
//如果没有,就创建一个类实例,并把值赋给存储类实例的变量
instance = new Singleton1();
}
return instance;
}
}
"懒汉式"单例模式特点
以时间换空间:
延迟加载,在需要的时候才实例化对象,节省了部分空间,避免了因为没有使用而造成的浪费。
线程安全性:
不安全,可能会存在同时调用构造方法,当第一次调用时运行入构造方法,判断实例为null,在即将要实例的时候,cpu切换到第二次调用,又进入构造方法同时判断为null并成功实例化,这时候再返回第一次调用同样也进行了实例化,但这样会return两个不同的实例对象,造成线程安全问题(类似于银行取钱)。解决方法:加锁synchronized
“饿汉式”
"饿汉式"
顾名思义是饥渴难耐,在类被加载的时候立即实例化一个对象。
"饿汉式"示例
public class Singleton2 {
//定义一个变量来存储创建好的类实例
//直接在这里创建类实例,由虚拟机来保证只会创建一次
//这个类加载到内存的时候就会创建唯一的一份实例
private static final Singleton2 instance = new Singleton2();
//私有化构造方法,好在内部控制创建实例的数目
private Singleton2() {
}
//定义一个方法来为客户端提供类实例
//这个方法需要定义成类方法,也就是要加static
public static Singleton2 getInstance() {
//直接使用已经创建好的实例
return instance;
}
}
"饿汉式"单例模式特点
以空间换时间:
立即加载,在加载类的时候就会立即实例化一个对象。时间上没有延迟,但可能会造成实例化的对象没被使用从而对导致空间资源浪费。
线程安全性:
安全的
原文链接:单例模式,欢迎访问个人博客。