[设计模式]-单例模式

定义确保一个类只有一个实例,并提供一个全局访问点

类图

单例模式的三要素

  • 私有的构造方法
  • 指向自己实例的私有静态引用
  • 以自己实例为返回值的静态的公有的方法

懒汉式实现1:

/**
 *@author April
 *@Date: 2013-12-24
 */
public class SingletonA {
	//私有构造方法
	private SingletonA(){}
	//指向自己的私有静态引用
	private static SingletonA instance = null;
	//返回自己实例的公有静态方法
	public static SingletonA getInstance() {
		if (instance == null) {
			instance = new SingletonA();
		}
		return instance;
	}
}
懒汉式实现2:
/**
 * 懒汉式-延迟加载:
 * 比起SingletonA在方法中多了一个synchronized修饰符,可以保证线程安全。
 * 但是有个很大(至少耗时比例上很大,绝大部分的耗时都用在synchronized的同步上)的性能问题,
 * 多线程的时候每次都会在1这里产生阻塞
 */
public class SingletonB {
	private SingletonB(){}
	private static SingletonB instance = null;
	public synchronized static SingletonB getInstance() {	//1--
		if (instance == null) {
			instance = new SingletonB();
		}
		return instance;
	}
}
 
 
饿汉式实现:
/**
 * 恶汉式-急切加载:依赖JVM在加载该类时马上创建该类的实例。JVM保证任何线程访问instance静态变量前,一定先创建此实例
 */
public class SingletonC {
	private SingletonC(){}
	//在静态初始化器创建单件。保证线程安全
	private static SingletonC instance = new SingletonC();
	public static SingletonC getInstance() {
		return instance;
	}
}
双重锁定检查:
/**
 * 双重锁定检查:确保线程安全,又保证性能不受很大影响
 * 
 */
public class SingletonD {
	private SingletonD(){}
	/**
	 * volatile关键词:被其修饰的变量的值,将不会被本地线程缓存,
	 *		所有对该变量的读写都直接操作共享内存,从而保障多线程能正确处理该变量
	 * volatile只适用于java1.5及以上
	 */
	private volatile static SingletonD instance = null;
	public static SingletonD getInstance() {
		if(instance==null){
			synchronized(SingletonD.class){
				if (instance == null) {
					instance = new SingletonD();
				}
			}
		}
		return instance;
	}
}
更好的单例实现
Lazy initialization holder class 模式
  • 类级内部类:有static修饰的成员式内部类。
    • 相当于其外部类的static成分,它的对象与外部类对象间不存在依赖关系,因此可以直接创建。
    • 类级内部类中,可以定义静态方法
    • 类级内部类相当于其外部类的成员,只有在第一次被使用的时候才会被加载
  • 多线程缺省同步锁:多线程开发中,为解决并发问题,主要通过synchronized来加互斥锁进行同步控制。但某些情况下JVM已经隐含为你执行了同步,就不用自己再同步控制了,这些情况包括:
    • 由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时
    • 访问final字段时
    • 在创建线程之前创建对象时
    • 线程可以看见它将要处理的对象时
/**
 * 通过JVM保证线程安全,getInstance并没有同步,所以延迟加载没有增加任何访问成本
 */
public class SingletonE{
	/**
	 * 类级内部类,也就是静态的成员式内部类,只有在调用到时才加载,从而实现延迟加载
	 */
	private static class SingletonHolder{
		//静态初始化器,由JVM来保证线程安全
		private static SingletonE instance = new SingletonE();
	}
	private SingletonE(){ }

	public static SingletonE getInstance(){
		return SingletonHolder.instance;
	}
}

单例和枚举

单元素的枚举类型已经成为实现Singleton的最佳方法——《高效Java 第二版》
  • Java枚举类型实质上是功能齐全的类,因此可以有自己的属性和方法
  • Java枚举类型的基本思想是通过公有的静态final域为每个枚举常量导出实例的类
  • 从某种角度讲,枚举是单例的泛型化,本质上是单元素的枚举
  • /**
     * 枚举来实现单例模式的示例
     */
    public enum SingletonF{
    	//定义一个枚举元素,它就代表了Singleton的一个实例
    	uniqueInstance;
    	//示意方法,单例可以有自己的操作
    	public void singletonOperation(){ }
    }
    

单例模式的优点:

  • 在内存中只有一个对象,节省内存空间。
  • 避免频繁的创建销毁对象,可以提高性能。
  • 避免对共享资源的多重占用。
  • 可以全局访问。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值