设计模式之-----单例模式
来源:互联网 发布:java分支循环语句 编辑:程序博客网 时间:2024/06/13 14:37
单例模式
原文地址
引言
上篇博客我们介绍了设计模式的六大基本原则,从今天开始我们一起来看几种常见的设计模式,设计模式在代码编写中用途非常广泛,正因为如此,一位优秀的程序员,肯定也是可以灵活运用常见设计模式的。那么今天介绍的就是单例模式
简介
单例模式:确保每一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
使用场景
确保一个类只有一个对象的场景,避免多个对象消耗过多的资源,或者某种类型的对象只应该只有一个,例如:创建一个对象需要消耗的资源过多,如果访问IO和数据库等资源,这就要使用单例模式。
注意
1.构造函数不对外开放,一般为private2.通过一个静态方法,或者每句返回单例类对象。3.确保单例类的对象只有一个,尤其是在多线程的环境下。4.确保单例对象在反序列化的时候不会重新构建对象
单例模式的实现
一).饿汉模式
class Text { //构造函数私有化 private Text(){} private static final Text text = new Text(); //对外暴露,获取单例对象的接口 public static Text getText() { return text; }}
评价:虽然实现了单例模式,一开始类就进行了实例化,即使没有用到此实例,也占用了资源。从而导致了资源的浪费。
二).懒汉模式
class Text { private Text(){} private static Text text; public static synchronized Text getText() { if(text == null){ text = new Text(); } return text;}
评价:虽然满足了上面的问题,只有在使用的时候才进行实例化,但是还有一个问题,就是,当需要使用的时候,需要进行实例化,会降低反应时间,用户体验不佳。
三).Double Check Lock(DCL)实现单例
class Text { private Text(){} private static Text text = null; public static Text getText() { if(text == null){ synchronized (Text.class){ if(text == null){ text = new Text(); } } } return text; }}
简介:很多初学者可能回不明白这个过程,为什么要进行两次判空,我们现在就来介绍,首先我们看这行代码。
text = new Text();
其实上行代码并不是一个原子操作,也就是说不是一步完成的。大概做了以下几步。1.给text的实例分配内存。2.调用Text()的构造函数,初始化成员字段。3.将text对象,指向分配的内存空间,(此时的text才不是null)为了确保1-2-3执行顺序的不确定,所以使用了以上操作,当然在JDK1.5之后就使用volatile关键词就可以了。
四).静态内部类实现单例
简介:DCL在一定程度上解决了资源消耗,多余的同步,线程安全等问题,但是,他还是会在某种情况下出现问题,这个问题被称为双重检查锁定(DCL)失效,
class Text { private Text(){} public static Text getText() { return TextHolder.text; } //静态内部类 private static class TextHolder{ private static final Text text = new Text(); }}
评价:当第一次加载的时候不会对Text进行实例化,只有当第一次调用getText()的时候才会倒置虚拟机加载TextHolder类,然后进行对象的实例化,这种方式不仅解决了资源浪费的问题,还解决了线程安全,也能够保证单例对象的唯一性,同事延迟了单例的实例化,所以这是推荐的一种方式。
五).枚举实现单例
简介:枚举实现单例是推荐的方法,有以下好处1.线程安全 2.不会因为序列化而产生新实例 3.防止反射攻击
public enum Text { INSTANCE; public void doSomething(){ System.out.print("do sth."); }}
六).使用容器的方式实现单例
简介:这是一种将多个单例类注入到一个统一打管理容器中,给每个单例类设置相应的Key,然后保存到容器中,需要的时候再取出。
public class Text { private static Map<String,Object> objectMap = new HashMap<String, Object>(); private Text(){} public static void registerService(String key,Object instance){ if(!objectMap.containsKey(key)){ objectMap.put(key,instance); } } public static Object getService(String key){ return objectMap.get(key); }}
总结
总是单例模式的实现规则多种多样,具体选择哪种方法,还需要根据实际情况进行推敲,如果无法确定使用那种情况的,建议使用枚举,或者静态内部类的方式实现。
1 0
- 设计模式之 单例设计模式
- 设计模式之 单例设计模式
- 设计模式之单例设计模式
- 设计模式之-----------单例设计模式
- 设计模式之:单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之-单例设计模式
- 设计模式之单例设计模式 标签: 设计模式
- 设计模式之单例
- 设计模式之单例
- 设计模式之 单例
- 判断递增数组
- centos7.2上搭建ntp服务器,并实现时间同步
- hadoop 完全分布式 下 datanode无法启动解决方法
- miloyip大神的"游戏程序员学习之路"
- 2016迟到的总结2017坚定的展望
- 设计模式之-----单例模式
- 2017 希望能够成为一名优秀的前端工程师
- 大话TDD,BDD,ATDD的本质
- 用python实现蒙特卡洛的方法
- Flume安装与侍弄
- 框架 day81 涛涛商城项目-实现首页搜索功能,商品详情,描述,规格展示
- NodeJS-http
- 2016 博客导读总结 & 个人感悟
- 一个奔三程序员的2016年总结