创建型模式之六——单例模式
2015-10-14 13:08
281 查看
模式定义
单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。模式结构
单例模式只包含一个Singleton(单例角色);在单例类的内部实现只生成一个实例,同时它提供一个静态的getInstance()工厂方法,让客户可以使用它的唯一实例;为了防止在外部对其实例化,将其构造函数设为私有;在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例。
实例
在现实生活中,居民身份证号码具有唯一性,同一个人不允许有多个身份证号码,第一次申请身份证时将给居民分配一个身份证号,如果之后因为遗失等原因补办时,还是使用原来的身份证号码,不会产生新的号码。现使用单例模式模拟该场景。该实例类图如下所示:
public class IdentityCardNo { private static IdentityCardNo instance; private String no; private IdentityCardNo() { } public static IdentityCardNo getInstance() { if (instance == null) { System.out.println("第一次办理身份证,分配新号码"); instance = new IdentityCardNo(); instance.setIdentityCardNo("345963611245369"); } else { System.out.println("重复办理身份证,获取旧号码号码"); } return instance; } private void setIdentityCardNo(String no) { this.no = no; } public String getIdentityCardNo() { return no; } } // 测试类 public class Client { public static void main(String[] args) { IdentityCardNo no1, no2; no1 = IdentityCardNo.getInstance(); no2 = IdentityCardNo.getInstance(); System.out.println("no1 == no2 ? " + (no1 == no2)); String str1, str2; str1 = no1.getIdentityCardNo(); str2 = no1.getIdentityCardNo(); System.out.println("第一次号码:" + str1); System.out.println("第二次号码:" + str2); System.out.println("内容是否相等:" + str.equalsIgnoreCase(str2)); System.out.println("是否是相同对象:" + (str1 == str2)); } }
扩展
饿汉式单例饿汉式单例是在Java语言中实现起来最为方便的单例类,饿汉式单例类结构图如下所示:
在这个类被加载时,静态变量instance会被初始化,此时类的私有构造函数会被调用,单例类的唯一实例将被创建,
懒汉式单例
public class LazySingleton { private static LazySingleton instance = null; private LazySingleton() { } synchronized public static LazySingleton getInstance() { if (instance == null) instance = new LazySingleton(); return instance; } }
该懒汉式单例类实现静态工厂方法时使用了同步化机制,以处理多线程环境。
饿汉式单例类在自己被加载时就将自己实例化。单从资源利用效率角度讲,这个比懒汉式单例类稍差些。从速度和反应时间简单来讲,则比懒汉式单例类稍好些。然而,懒汉式单例类在实例化时,必须处理好多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源管理器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费大量时间,这就意味着多个线程同时首次引用此类的几率变得较大,需要通过同步化机制进行控制。
相关文章推荐
- 关于更新OS X EI后下得Xcode7下面的 cocoapods安装与使用
- nodejs express框架解决跨越问题
- 安装ecshop出现{“res”:”false”,”rsp”:”\u7f3a\u5c11\u5fc5\u8981\u7684\u53c2\u6570″}的解决方法
- 剑指offer第八题【跳台阶】c++实现
- 手机质量投诉居榜首
- new char[]返回一个地址
- 理解HTTP协议
- 江苏10批次老人手机仅1批次合格
- 开源pfsense修改初始登录账户和密码的解决方法
- Writing Images to the Excel Sheet using PHPExcel--转载
- 中小手机厂商遇倒闭潮:沦为小米华为炮灰
- 【微信插件】P3微信插件测试使用步骤
- ALAsset,ALAssetsLibrary,ALAssetsgroup常见属性及用法
- Mac 下Versions的 svn无法上传 .a 文件的问题
- IOS笔记UI--禁止scrollview上下拖动
- C语言回顾 九 高级指针
- eclipse快捷键汇总
- tomcat6如何配置ssi使其支持shtml?
- Java核心技术第6章(2)
- 线程基础知识