设计模式之---单例模式总结

       每到年底我都会出去面试看看情形怎么样,今年无疑是就业行情最差的一年,有些单位招人存粹拿行情说事,最高给我的月薪只有税前10K,这让我现在税后都不止的薪水情何以堪啊。因为在游戏行业里面的缘故,索性接触不到最新的Android技术,但是有时候会被很基础的东西给问死,比如我现在就要说到单例模式。网上有人总结了七八种,都是稍微修改一下就是另外一种,觉得不是很负责。总之大体就是饿汉式和懒汉式还有静态内部类,其他的答题一致,这里我自不量力的再来总结了一下模式实现的方式。使用场景是:确保某个类有且只有一个对象,这样可以避免生成多个对象消耗过多的资源。

     - **饿汉式**

     - **懒汉式**

     - **静态内部类**


      饿汉式

     

public class Singleton {
	private static Singleton sSingleton = new Singleton();

	private Singleton() {
	}

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

     简单粗暴,直接使用,还没有线程安全的隐患,这是很多人热衷的原因,但是,在每次加载Singleton类的时候就直接实例化对象了相比之下就浪费资源了。浪费资源了。


   懒汉式

public class Singleton {
	private static Singleton sSingleton = null;

	private Singleton() {
	}

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

这样对于单线程就可以直接使用了,但是,对于多线程来说就会存在安全隐患,因为多线程抢占CPU的情况下,代码的执行顺序变成异步的了。所以,通常会加上同步锁。

public class Singleton {
	private static Singleton sSingleton = null;

	private Singleton() {
	}

	public static synchronized Singleton getInstance() {
		if (sSingleton == null) {
			sSingleton = new Singleton();
		}
		return sSinglen;
	}
}

    这样虽然是在使用的时候才实例化对象,一定程度上节约了资源,但是每次调用getInsatnce方法的时候,都会进行同步,这样会消耗不必要的资源,占用同步开销,并且在第一次加载的时候要及时进行实例化,反应会稍微慢点。于是,面对上面的问题,伟大的人类想出了D模型来实现。

public class Singleton {
	private static Singleton sSingleton = null;

	private Singleton() {
	}

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

添加了一个双重判断机制,这样可以 不用同步锁,又能保证线程安全。但是在线程执行到sSingleton = new Singleton()的时候并不是一个原子操作,由于java编译器允许处理器乱序执行,在初始化成员字段和将对象只想分配的内存空间的时候,这里写代码片on sSingleton = new Singleton()的时候并不是一个原子操作,由于java编译器允许处理器乱序执行,在初始化成员字段和将对象只想分配的内存空间的时候这样的顺序是不一定的。如果反过来了,就会出错了。


静态内部类

public class Singleton {
	
	private Singleton(){}
	
	public static Singleton getInstance(){
		
		return SingletonCreate.sSingleton;
	}
	
	private static class SingletonCreate{
		private static final Singleton sSingleton = new Singleton();
	}
}

这是目前把上面的顾虑都解决了的最好实现方式。第一次加载不会初始化实例,只有在调用getInstance方法的时候才会初始化,第一次调用这个方法的时候会导致虚拟机加载SingletonCreate这个静态类,这种方式不仅可以保证线程安全,也能保证对象的唯一性,同时演示了单例的实例化。

除此之外还有枚举和容器的实现,但是这些相信十个人都不一定有一个人会用到,就不写了。

       面试的时候就问道静态内部类的时候为什么会是最好的选择,当时见识短,没怎么去想,现在回头看看自己当时是有多无知啊,稍微理解下基本就可以回答上来,还是太年轻了。好在,面试碰到的问题基本是提升的最好最快途径,所以没事面个试,就知道自己的分量和积累问题的经验了。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值