设计模式之单例模式详解和使用方法
单例模式的定义
在单实例模式下,只会存在一个实例,实例将自己实例化并提供给整个系统使用。我们熟知的线程池、高速缓存、日志对象、对话框、打印机和显卡驱动程序对象通常设计为单例模式。这些应用程序都具有资源管理器的功能。举个例子来说明一下,比如每台计算机可以有多台打印机,但为了避免多个打印机同时打印到打印机上, 每个计算机可以具有多个通信端口,并且系统必须集中管理这些通信端口,使得一个通信端口不能被两个活多个打印机请求并且同时调用。也就是说,选择单一模式是为了避免不一致状态。
单例模式类的特征
a、只有一个实例。
b、必须自己创建自己的唯一实例。
c、单个实例类必须为所有其他对象提供此实例。
单例模式的UML结构图如下:
单例模式的种类
单例模式通常包含懒汉式、恶汉式、双重检测锁式、静态内部类式和枚举单例等5种方式,下面我们针对这5种情况一一进行详解:
1、懒汉式
懒汉式模式是线程不安全的,此模式是在运行时才开始加载对象的,使得其加载速率较快,但是对象的检索速度会变得比较慢。如果您希望线程安全,那么就使用关键字synchronized,如果这样的话就效率就会慢,应谨慎使用。代码如下:
public class SingletonDemo {
//线程不安全的
private static SingletonDemo instance = null;
private SingletonDemo() {
}
//运行时加载对象
public static SingletonDemo getInstance() {
if (instance == null) {
instance = new SingletonDemo();
}
return instance;
}
}
2、恶汉式
他的特点是线程安全,效率也高,但是无法延迟加载,此模式在加载类时创建了对象,加载类的速度较慢,取对象的速度较快,线程安全。
示例代码如下:
public class SingletonDemo {
//线程安全的
//类初始化时,立即加载这个对象
private static SingletonDemo instance = new SingletonDemo();
private SingletonDemo() {
}
//方法没有加同步块,所以它效率高
public static SingletonDemo getInstance() {
return instance;
}
}
3、双重检测锁式
这个模式的实现原理是在getInstance()方法内对instance实例进行两次费控判断,他的优点是资源的利用率高,效率高,缺点是第一次初始化加载的时候速度较慢,还有可能会失效,代码如下:
private volatile static SingletonDemo instance;
private SingletonDemo() {
}
public static SingletonDemo getInstance() {
if (null == instance) {
synchronized (SingletonDemo.class) {
}
if (null == instance) {
instance = new SingletonDemo();
}
}
return instance;
}
4、静态内部类式
他的实现原理请见如下代码:
private static class SingletonHolder {
private static final SingletonDemo INSTANCE = new SingletonDemo();
}
private SingletonDemo() {
}
public static final SingletonDemo getInstance() {
return SingletonHolder.INSTANCE;
}
5、枚举单例
此模式的优点是书写简单,并且能防止单例模式被破坏以及防止用java的反射机制获取枚举类的对象,代码如下:
public enum EnumSingleton {
INSTANCE;
public EnumSingleton getInstance(){
return INSTANCE;
}
}
原创声明:本文为【Java学习提升】原创博文,转载请注明出处。
本文来源于公众号:【Java学习提升】 专注于Java领域技术分享,Java知识体系学习、分享面试经验,让我们结伴而行,共同成长!
上一篇: 求1000阶乘的结果末尾有多少个0