Singleton--单例模式

[导读]

         单例模式,顾名思义,只有一个实例。很多应用场景下,一个服务,一个组件都会以单例来运行。具体到一个类,一个类只能创建一个对象。

[正文]

1. 单例模式特征

(1). 外界不能显示创建对象,所以构造函数必须为private;

(2). 给外界提供唯一的访问实例的接口,一般名字为:getInstance(), 返回唯一的对象实例;

故单例类的类图可以表示为:


2. 模式实现

模式实现这一块内容相当丰富,尤其是在<<effective java>>里讨论得很精彩。按理说没有必要在这里累赘,就当烂笔头吧。

【实现1】

class Singleton {
	private static Singleton instance = null;
	
	private Singleton(){
		
	}
	
	public static Singleton getInstance() {
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}
【分析】上述实现为非线程安全,即在多线程环境下,可能产生多个实例,违背了单例的概念语义。


【实现2】

class Singleton {
	private static Singleton instance = null;
	
	private Singleton(){
		
	}
	
	public synchronized static Singleton getInstance() { // 比上面多了一个synchronized关键字
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}

【分析】上述实现加了一个类级锁,能保证只创建一个实例,但每次取得实例意味着加锁一次,是否有效率提升的空间呢?


【实现3】

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

【分析】上述实现就是最经典的double-check locking实现,在多线程环境里不是每个线程都会进入到synchronized同步模块。对于每一个线程,要获取实例都需要做第一层的if判断,依然是效率的问题。当然对比【实现2】,效率已经有了提升。


【实现4】

class Singleton {
	private static Singleton instance = new Singleton();
	
	private Singleton(){
		
	}
	
	public static Singleton getInstance() {
		return instance;
	}
}
【分析】上述实现能直接获取单例实例,不用加锁,也不用做任何判断,效率达到了最佳。但是java的静态变量是不管你用不用,只要进程启动,静态变量都会初始化。能优化吗?


【实现5】

class Singleton {
	
	private Singleton(){
		
	}
	
	public static Singleton getInstance() {
		return SingletonMaker.instance;
	}
	
	private static class SingletonMaker{
		public static Singleton instance = new Singleton();
	}
}

【分析】增加一个私有静态内部类

(1).静态类不是变量, 所以SingletonMaker类里的成员不会在一开始就初始化

(2). 内部静态类,对外不可见。对内和Singleton是相互可见的。因此由它来创建单例实例,既能满足效率问题,又能避免资源集中在初始阶段去初始化。

这也是lazy load的实现。


ok了。最后一种当然也是最佳实现方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值