设计模式(五) 单例模式(Singleton)

单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点。适用于类只能有一个实例且需要全局访问的情况,如配置管理。单例模式包括在类装载时创建静态实例的实现方式,使用volatile关键字防止指令重排序。
摘要由CSDN通过智能技术生成

1.定义

单例模式是一种创建型的设计模式。单例模式意在保证一个类仅有一个实例,并且提供一个全局的访问点。


2.适用性

  • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时


一个国家只有一个主席/总统,一个人只有一个名字/身份证号,这些都是单例的例子。稍微实际点的例子就是,在某个服务器程序中,将服务器的配置信息存放在一个文件中,这些配置数据有一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。


3.结构


参与者:

Singleton

—— 定义一个Instance操作,允许客户访问它的唯一实例。Instance是一个类操作

—— 可能负责创建它自己的唯一实例


4.举例

我们先来实现一个简单的单例:


package com.andy.designpattern.singleton;

public class Singleton {
	private static Singleton instance = null;

	private Singleton() {
	}

	public static Singleton getInstance() {
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}

}

 我们将构造函数设为private类型,使得客户无法构造多余的实例;instance设为类的类变量,保证类只有一个。乍看之下,这样的实现已经很完美了,但是这个方案在遇到多线程的时候还是会出问题:几个线程同时请求getInstance,可能多个线程同时通过if(instance == null)的检查,这样就可能产生多个实例。所以我们需要对上面的例子进行改进。 

第一个中改进方案是在类装载的时候构建静态单例,请求get的时候直接返回:

package com.andy.designpattern.singleton;

public class Singleton {
	private final static Singleton INSTANCE = new Singleton();

	private Singleton() {
	}

	public static Singleton getInstance() {
		return INSTANCE;
	}
}

第二种改进方案是通过synchronized、volatile等关键字将原始方案改写为线程安全的方案(此方案只适用于JDK5之后的版本,之前的版本使用“双重检查锁”会发生非预期行为):

package com.andy.designpattern.singleton;

public class Singleton {
	private static volatile Singleton INSTANCE = null;

	private Singleton() {
	}

	public static Singleton getInstance() {
		if (INSTANCE == null) {
			synchronized (Singleton.class) {
				if (INSTANCE == null) {
					INSTANCE = new Singleton();
				}
			}
		}
		return INSTANCE;
	}

}
这里为什么需要检查两次INSTANCE == null呢?

  • 第一次检查if(INSTANCE == null)是判断INSTANCE是否被创建,如果已创建,就直接返回;否则开始线程同步
  • 第二次检查if(INSTANCE == null)是判断在同步的线程当中是否有线程已经创建了INSTANCE,若有,则返回;否则创建并返回。

把INSTANCE声明为volatile有两个作用:

  • 这个变量不会再多个线程中存在复本,直接从内存中读取
  • 这个关键字会禁止指令重排序优化。


5.总结

其实单例模式还是比较简单的,就是说一个类只能有一个实例,于是我们把它声明为一个类的类变量,需要使用时判断是否存在,若存在即返回;若不存在,则调用私有构造器构造并返回。


6.参考文献

  1. 维基百科——单例模式
  2. 设计模式学习笔记十:单例模式 by 竹子-博客
  3. 深入浅出单实例Singleton设计模式 by 陈皓
  4. Design Pattern - Singleton Pattern



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值