java设计模式-单例模式
单例模式
其定义为:单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的一个类只有一个实例。即一个类只有一个对象实例。
实现单例模式的方式
单例模式的实现方式有很多,主要有饿汉模式,懒汉模式,静态内部类,注册登记模式以及通过实现序列化也可以实现单例模式。
饿汉模式
public class Hungry { private Hungry(){} private static final Hungry hungry = new Hungry(); public static Hungry getInstance(){ return hungry; } }
懒汉模式
//在外部需要使用的时候才进行实例化 public class LazyOne { private LazyOne(){} //静态块,公共内存区域 private static LazyOne lazy = null; public static LazyOne getInstance(){ //调用方法之前,先判断 //如果没有初始化,将其进行初始化,并且赋值 //将该实例缓存好 if(lazy == null){ lazy = new LazyOne(); } //如果已经初始化,直接返回之前已经保存好的结果 return lazy; } }
静态内部类
public class LazyThree { //默认使用LazyThree的时候,会先初始化内部类 //如果没使用的话,内部类是不加载的 private LazyThree(){} //static 是为了使单例的空间共享 //保证这个方法不会被重写,重载 public static final LazyThree getInstance(){ //在返回结果以前,一定会先加载内部类 return LazyHolder.LAZY; } //默认不加载 private static class LazyHolder{ private static final LazyThree LAZY = new LazyThree(); } }
注册登记模式
//注册式单例 public class RegisterMap_bxc { //相当于本地缓存 private static Map<String,Object> regist = new HashMap<String,Object>(); public static RegisterMap_bxc getInstance(String name) { if(null == name) { name = RegisterMap_bxc.class.getName(); } synchronized (regist) { if(!regist.containsKey(name)) { regist.put(RegisterMap_bxc.class.getName(),new RegisterMap_bxc()); } return (RegisterMap_bxc)regist.get(name); } } }
总结
饿汉模式:
优点:饿汉模式是线程安全的,而且执行效率比较高,从用户的体验来说比懒汉好
缺点:因为它在类加载的时候就初始化了,不管是否用到,所以饿汉模式浪费系统资源
懒汉模式:
优点:在类加载的时候不会初始化,只有当调用的时候才会初始化,所以比较节约资源
缺点:线程不安全,高并发的情况下容易出错
静态内部类:
可以说静态内部类综合了懒汉和饿汉模式,在外部类调用的时候,内部类才会被初始化,而且避免了线程安全性的问题
注册登记模式:
spring中就是用这种方法来管理实例的,目前对源码还在研究中,这里就不多说了。