Java设计模式----单例模式

单例设计模式所解决的问题就是:保证类的对象在内存中唯一。

1、饿汉

/**
 * @说明:饿汉模式
 * 解决思路:
 *	1.不允许其他程序使用new创建该类对象。(别人new不可控)
 *	2.在该类中创建一个本类实例。
 *	3.对外提供一个方法让其他程序可以获取该对象。
 * 步骤:
 *  1.私有化该类的构造函数
 *  2.通过new在本类中创建一个本类对象。
 *  3.定义一个共有的方法将创建的对象返回。
 * @author heyanpeng
 */
public class Single {
	
	private final static Single sigle = new Single();
	
	// 私有化构造函数
	private Single () {
		
	}
	
	public static Single getInstance(){
		return sigle;
	}
}

2、懒汉

/**
 * @说明:懒汉模式
 * 	延迟对象创建,第一次使用的时候创建,节省了内存空间
 * 	存在的弊端:多线程编程中,使用懒汉式可能会造成类的对象在内存中不唯一
 *  
 * @author heyanpeng
 */
public class Single2 {

	private static Single2 single2 = null;
	
	// 私有化构造函数
	private Single2(){
		
	}
	
	public static Single2 getInstance(){
		if (null == single2) {
			single2 = new Single2();
		}
		return single2;
	}
}

总结:
懒汉式在面试的时候经常会被提到,因为知识点比较多,而且还可以和多线程结合起来综合考量。
饿汉式在实际开发中使用的比较多。

3、懒汉式多线程优化

/**
 * @说明:懒汉多线程优化
 * 	在懒汉模式下,if(null == single2) 的判断存在线程安全
 *  
 * @author heyanpeng
 */
public class Single3 {
	
	private static Single3 single3 = null;
	
	// 私有化构造函数
	private Single3(){
			
	}
	
	/**
	 * 方案1: 方法增加synchronized同步
	 */
	public static synchronized  Single3 getInstance(){
		if (null == single3) {
			single3 = new Single3();
		}
		return single3;
	}
	
	/**
	 * 方案2: 代码块增加synchronized同步
	 */
	public static  Single3 getInstance2(){
		synchronized(Single3.class){
			if (null == single3) {
				single3 = new Single3();
			}
			return single3;
		}
	}
	
	/**
	 * 方案3: 为空的时候加synchronized同步,再进行为空判断
	 */
	public static  Single3 getInstance3(){
		if (null == single3) {
			synchronized(Single3.class){
				if (null == single3) {
					single3 = new Single3();
				}
			}
		}
		return single3;
	}
}

总结:假设我们现在并没有创建单例对象,即snull,那么我们调用getInstance方法的时候,会进入if块,然后进入同步代码块,此时,别的线程如果想要创建Single实例,就必须获取锁;等当前线程创建完实例对象,释放锁之后,假设正巧有几个线程已经进入了if块中,它们会拿到锁,进入同步代码块,但是由于进行了判空操作,所以不会创建Single实例,而是直接返回已经创建好的Single实例。如果有多个其他线程进入了if块,当它们依次进入同步代码块的时候,同理也不会创建新的Single实例。而没有进入if块的线程,判空操作之后不满足条件,进不了if块,而直接执行了下一条语句return s;其后的线程调用getInstance方法时,只会判断一次snull,不满足条件直接返回Single单例s,这样就大大提高了了执行效率。
第一行代码是第一次判空操作,目的是提高效率;第三行代码是同步代码块的入口,目的是保证线程安全;第五行代码进行第二次判空操作是为了保证单例对象的唯一性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值