`
lcwyiyun
  • 浏览: 11827 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

第二天 单例模式

 
阅读更多
        单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

        实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。

        单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。

饿汉式,指全局的单例实例在类装载时构建。
public class Singleton {
	private static Singleton instance = new Singleton();

	private Singleton() {
	}
	
	public static Singleton getInstance() {
		return instance;
	}
}


懒汉式,指全局的单例实例在第一次被使用时构建
public class Singleton {
	private static Singleton instance = null;

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

单例的陷井:
多个虚拟机
        当单例类被运行在多个虚拟机下的时候,在每个虚拟机都可以创建一个实例对歇脚。像使用了EJB,JINI,RMI技术的分布式系统的时候,因为中间件屏蔽了分布式系统在物理上的差异,这个时候想知道在哪个虚拟机下运行着哪个单例对象很困难。因此在使用分布式技术时,应该避免使用
多个类加载器
        当存在多个类加载器,即使它们加载的相同包名,相同类名甚至每个字节都完全相同的类,也会被区别对待的。因为不同的类加载器会使用不同的命名空间来区分同一个类,因此,单例类在多加载器的环境下会产生多个单例对象。也许你认为出现多个类加载器的情况不多,其实多个类加载器存在的情况不少,在很多J2EE服务器上允许存在多个SERVLET引擎,而每个引擎是采用不同的类加载器的,浏览器的APPLET小程序通过网络加载类的时候,由于安全因素,采用的是特殊类加载器,等等。
        在这种情况,由状态的单例模式也会给系统带来隐患。因此除非系统由协调机制,在一般情况下不要使用存在状态的单例模式。

错误的同步处理
        在使用上面介绍的懒汉式单模式的时候,同步得理恰当与否也是很,不然要能达不到想要的单例效果,还可能引发死锁等。因此在使用懒汉式单例模式时一定要对同步有所了解,不过使用饿汉式单例模式就可以避免这个问题。

子类破坏了对象控制
        如果构造器变得不再私有,就有可能失去对对象的控制。

串行化(可序列化)
        为了使一个单例类变成可串行化的,仅仅在声明中添加“implements Serializable"是不够的,因为一个串行化的对象在每次反串行化的时候,都会创建一个新的对象,而不仅仅是一个对原有对象的引用,为了防止这种情况,可以在单例类中加入readResolve方法。对象的反串行化并不仅局限于上述方式,还存在基于 XML模式的对象串行化方式,这种方式也存在上述的问题,所以在使用的时候还要格外小心。
public class Singleton implements Serializable{
	private static Singleton instance = null;

	private Singleton() {
	}
	
	public static Singleton getInstance() {
		if(instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
	
	private Object readResolve() throws ObjectStreamException {
		return instance;
	}
}
分享到:
评论

相关推荐

    java 采用单例模式计算当年有多少个周,并列出所有周以及每一个周所对应的时间段(内含注释)

    根据给定文件的信息,本文将详细解析如何使用Java语言及单例模式来计算并列出一年中的所有周及其对应的时间段,同时也会展示如何获取当前日期及其所在周。 ### 一、单例模式简介 单例模式是一种常用的软件设计模式...

    设计模式第二天学习内容

    第一次 `instance == null` 判断是为了避免不必要的同步,第二次判断则是为了确保在多线程环境下只有一个线程能执行 `instance = new DoubleCheckLockSingleton();` 这一行,从而保证线程安全。 另一种懒汉式的实现...

    mybatis第二天课堂笔记

    通常情况下,`SqlSessionFactory` 在整个应用中作为单例模式使用。 3. **创建 SqlSession**:从 `SqlSessionFactory` 获取 `SqlSession` 实例。`SqlSession` 提供了一系列用于执行 SQL 语句的方法,如 `select`、`...

    mybatis第二天课堂笔记.doc

    `SqlSessionFactory`是线程安全的,一般以单例模式使用。 3. **打开SqlSession**:通过`SqlSessionFactory`创建`SqlSession`实例。`SqlSession`不是线程安全的,推荐在一次请求内使用一个`SqlSession`。 4. **执行...

    毕向东静态07

    【描述】"Java基础视频教程第06天-10-面向对象(单例设计模式方式二)"深入讲解了面向对象设计中的单例模式。单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统资源管理、数据库...

    北京中科信软VS.NET设计模式与软件架构设计培训1

    第二天的课程深入到软件架构设计的具体过程,包括编写软件设计文档、架构师在立项阶段的工作,以及如何使用MSF和MOF(Microsoft Operation Framework)结合来覆盖软件生命周期。课程详细讲解了概念设计、物理设计、...

    Springmvc第二天课程文档

    通常情况下,`SqlSessionFactory`应作为单例存在。 3. **获取会话**:通过`SqlSessionFactory`创建`SqlSession`实例,它是用户与数据库交互的主要接口,实现了线程不安全的操作。 4. **执行操作**:调用`SqlSession`...

    第十二天 02__new__和__init__方法【千锋Python人工智能学院】1

    `__new__`的主要作用在于可以控制对象的创建过程,例如在实现单例模式时,确保只有一个实例存在。 接下来,`__init__`方法是类的实例方法,它在`__new__`之后被调用,用于初始化新创建的对象。`__init__`接收一个...

    mfc程序防止程序重复打开

    当用户尝试打开第二个实例时,程序会检测到已有实例的存在,然后激活并聚焦到原有的实例,而不是创建新的窗口。这种方法既简单又实用,适用于大多数MFC应用程序的需求。 请注意,虽然这个方法在大多数情况下都能很...

    Spring框架是在2003年兴起的一门轻量级的JAVAEE框架技术 Spring框架学习资料第一天

    * Spring框架采用了很多的设计模式:单例模式、工厂模式、代理模式、适配器模式、观察者模式、策略模式、装饰器模式等等 二、工厂设计模式实践 * 工厂设计模式主要目的是通过工厂类生产对象 * 工厂实践的步骤: 1...

    VC++21天教程

    **第二天至第四天:C++基础知识** 在这几天,你会深入学习C++的基础知识,如变量、数据类型、运算符、控制结构(如if-else,switch-case,循环)、函数、数组和指针。这些是任何C++程序员必备的基础,也是VC++编程...

    设计模式例题

    3. **单例模式**:确保某些类在系统中只有一个实例,并提供一个全局访问点。例如,可以为财务系统、库存系统等设计单例类,保证在整个应用程序中只使用一个实例。 此外,对于案例中提到的订单打印程序,可以使用...

    J2EE面试题及答案(包含数据库题)

    第二次创建`B`对象时,静态块只执行一次,所以输出`1a2bab`。这体现了类加载和构造器调用的顺序。 4. 单例模式: `Singleton`类的实现展示了饿汉式单例模式,即在类加载时就创建了单例实例。`private static ...

    java视频教程_黑马Java零基础辅导班[第二期]15天课件源码

    【Java视频教程_黑马Java零基础辅导班[第二期]15天课件源码】是一套专为初学者设计的全面Java学习资源。这个教程旨在帮助那些对编程没有基础或者对Java语言不熟悉的学员,通过15天的密集学习,掌握Java编程的基本...

    北大青鸟 第二单元项目

    【北大青鸟 第二单元项目】是一个以Java编程语言实现的教育项目,源自知名的IT培训机构北大青鸟。这个项目的重点在于提升学员的实践能力,通过实际的编程任务来加深对Java语言的理解。在这个项目中,学员们将面临一...

    JavaScript模块化编程七日

    第二天:ES6模块 - 学习ES6的`import`和`export`语法,理解静态导入和动态导入的区别。 - 使用`default`导出和命名导出,掌握默认导出与多个导出的用法。 - 探讨模块循环引用的问题及其解决方案。 第三天:模块打包...

    毕向东java全部25天教程下载地址

    - **单例模式**:理解单例模式的实现方法及其应用场景。 - **模板模式**:学习模板模式的概念和使用场景。 - **策略模式**:掌握策略模式的设计思想及其在实际项目中的应用。 #### Java API 与框架 - **Java API ...

Global site tag (gtag.js) - Google Analytics