设计模式之五 单件模式

  • 单件模式

定义

单件模式确保一个类只有一个实例,并提供一个全局访问点。

优缺点

优点:全局变量需要在程序启动时创建好对象(有的JVM的实现是:在用到的时候创建对象),消耗不必要的资源,而单件模式可以在我们需要时才创建对象,和全局变量一样方便,又没有全局变量的缺点。

应用场景

有一些对象我们其实只需要一个,比方说:线程池(threadpool)、缓存(cache)、对话框、偏好设置和注册表(registry)的对象、日志对象、打印机的驱动程序的对象。

例子

经典的单例模式的实现(如果我们不需要这个实例,它就永远不会产生,这就是“延迟实例化”)

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

处理多线程(在多线程情况下,有可能出现创建多个实例的 情况),下面是一种解决方法:

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

但是这样做的缺点很明显:降低性能。而且只有第一次执行此方法时,才需要同步。一旦创建好uniqueInstance后,就不需要同步这个方法了。

下面是一些选择:

1.如果getInstance()的性能对应用程序不是很关键,就什么也别做。

2.使用“急切”(eagerly)创建实例,而不用延迟实例的做法。(JVM在加载这个类时,马上创建实例)

public class Singleton {
	private static Singleton uniqueInstance = new Singleton();
	
	private Singleton() {}

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

3.用双重加锁,用双重检查加锁(double-checked locking),首先检查实例是否创建,如果尚未创建,“才”进行同步。这样一来,只有第一次会同步。(volatile支持jdk1.4以上版本)

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

 

设计原则

封装变化

多用组合,少用继承

针对接口编程,不针对实现编程

为交互对象之间的松耦合设计而努力

类应该对扩展开放,对修改关闭

依赖抽象,不要依赖具体

小结

对多线程使用单件模式要尤其注意,加锁或“急切”创造实例的方法视情况选择。

小知识

volatile关键字:

一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

  1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

  2)禁止进行指令重排序。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值