`
ldjsyl
  • 浏览: 194686 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

设计模式-单例模式(续)

阅读更多
《设计模式-单例模式》这篇文章中对单例模式做了一个简单的介绍,接下来本文主要讨论的是多例模式、多线程、双重检查以及“不完全”单例类。

一、多例模式
所谓多例模式,实际上就是单例模式之自然推广,单例类一般情况下只可以有一个实例,但单例类也可以推广到允许有限个实例,这种模式就是多例模式,它的主要特点:多例类可以有多个实例。

二、多线程
下面这段代码使用了线程同步,可以说是线程安全的,一个类不会出现多个实例。如果没有synchronized同步,则在单线程中是安全的,但是到多线程中就可能会出现多个实例。 
public class LazySingleton        
{        
private LazySingleton m_instance;
private LazySingleton() { }       
  
//对静态工厂方法使用了同步化,以处理多线程环境   关键字synchronized
synchronized public static LazySingleton getInstance()     
{        
   if (m_instance == null)        
   {        
       m_instance = new LazySingleton();        
   }        
   return m_instance;        
  }       
}


三、双重检查
仔细观察一下上面的例子,发现同步只是在m_instance没有被创建之前也就是第一次执行此方法时,明显降低性能。有两种方式可以改善,一就是饿汉式单例模式,另外一种就是双重检查。如下面的代码所示:
public class LazySingleton        
{        
private LazySingleton m_instance;
private LazySingleton() { }       

public static LazySingleton getInstance()     
{        
   if (m_instance == null)//first cheak
   {
       synchronized(this)
       {
         if (m_instance == null)//second cheak
         {
            m_instance = new LazySingleton();
         }
       }        
   }        
   return m_instance;        
  }       
}

但是看了《Java与模式》后才发现这样是不行的,虽然想法是好的!不成立的基本原因在于,在Java 编译器中,LazySingleton 类的初始化与m_instance变量赋值的顺序不可预料。如果一个线程在没有同步化的条件下读取m_instance 引用,并调用这个对象的方法的话,可能会发现对象的初始化过程尚未完成,从而造成崩溃。

但是根据最新的JSR133的java内存模型,如果将引用类型声明为volatile,双重检查模式就可以工作了。如下:
public class LazySingleton        
{        
  private volatile LazySingleton m_instance;//将引用类型声明为volatile
  private LazySingleton() { }       

  public static LazySingleton getInstance()     
  {        
    if (m_instance == null)//first cheak
    { 
       synchronized(this)
       {
         if (m_instance == null)//second cheak
         {
            m_instance = new LazySingleton();
         }
       }        
    }        
    return m_instance;        
  }       
}


四、不完全单例类
如下面的代码所示,看起来好像是懒汉式单例类,但是细看一下,才发现没有隐藏构造函数。这就是不完全单例类。
public class LazySingleton 
{ 
  private static LazySingleton 
  m_instance = null; 
  /** 
  * 公开的构造子,外界可以直接实例化 
  */ 
  public LazySingleton() { } //注意:这里是public
  /** 
  * 静态工厂方法 
  * @return 返还LazySingleton 类的惟一实例 
  */ 
  synchronized public static LazySingleton getInstance() 
  { 
    if (m_instance == null) 
    { 
      m_instance = new LazySingleton(); 
    } 
    return m_instance; 
  }
}
1
1
分享到:
评论

相关推荐

    二十三种设计模式【PDF版】

    设计模式之 Singleton(单态/单件) 阎宏博士讲解:单例(Singleton)模式 保证一个类只有一个实例,并提供一个访问它的全局访问点 设计模式之 Factory(工厂方法和抽象工厂) 使用工厂模式就象使用 new 一样频繁. ...

    IOS基于ASIHttpRequest的封装,使用单例模式断点续传

    3. **单例模式**:在iOS开发中,单例是一种设计模式,常用于管理共享资源或全局状态。在这个项目中,使用单例模式创建一个全局的网络请求管理者,确保在整个应用生命周期内只有一个实例存在,这样可以方便地跟踪和...

    labview 设计模式

    ### LabVIEW设计模式详解 #### 一、LabVIEW设计模式概览 LabVIEW作为一种图形化编程语言,在自动化测试和测量领域有着广泛的应用。随着软件规模的不断扩大和技术需求的日益复杂,设计模式在LabVIEW开发中变得...

    设计模式可复用面向对象软件的基础.rar

    它可能展示了如何在实际项目中运用设计模式,比如可能是介绍了一个下载管理器的实现,其中可能包含了策略模式的应用,通过切换不同的下载策略(如线程数控制、断点续传等)来适应不同的网络环境。 "说明.htm"则可能...

    23设计模式简讲

    - **模式定义**:单例模式是一种创建型设计模式,它保证一个类仅有一个实例,并提供一个全局访问点。 #### 结构型模式 6. **ADAPTER** - **场景解析**:在一次聚会中遇到了来自香港的美女Sarah,但由于语言障碍...

    JAVA 版本 断点续传

    - 单例模式管理文件传输的状态信息,确保全局唯一。 - 观察者模式用于监听传输进度,及时更新用户界面。 6. **挑战与优化**: - 网络波动可能导致传输失败,需要有重试机制。 - 高并发下的资源竞争和同步问题,...

    毕业设计-酒店管理系统

    同时,设计模式如工厂模式、单例模式、代理模式等的运用,提高了代码的可读性和可维护性。 六、安全性与性能优化 .NET框架提供了强大的安全机制,如身份验证、授权、加密等。在性能优化方面,可以利用缓存策略、...

    Java多线程与线程安全实践-基于Http协议的断点续传.zip

    7. **设计模式**:可能用到的设计模式包括单例模式(为全局资源管理提供唯一入口)、工厂模式(创建线程对象)以及模板方法模式(定义线程的基本行为)等。 8. **源码分析**:这个项目包含73个子文件,意味着可能有...

    Windows应用高级编程-C#编程篇 续

    9. **设计模式**:学习并应用各种设计模式,如工厂模式、单例模式、观察者模式等,提升代码可维护性和复用性。 10. **UWP应用开发**:UWP提供了一种统一的跨设备开发方式,可以创建适用于Windows 10的现代应用,...

    ACCP5.0-S1-C#项目教程(续)

    9. **设计模式**:介绍常见的设计模式,如单例模式、工厂模式、观察者模式等,提升代码的可维护性和可扩展性。 每个PPT文件(TP5V1.0.ppt、TP6V1.0.ppt、TP8V1.0.ppt、TP7V1.0.ppt)可能会对应课程的不同部分,比如...

    iOS 断点续传

    3. **单例模式**:描述中提到的“通过单例模式快速获取对象”是指在iOS应用中,为了方便全局访问和管理断点续传的状态,通常会使用单例设计模式来创建一个共享的下载管理器。这样,任何地方都可以随时查询或控制下载...

    JAVA学习笔记

    在笔记中,可能会深入探讨类与对象、接口、抽象类等核心概念,以及如何运用设计模式如工厂模式、单例模式和观察者模式等。 其次,JAVA的多线程设计模式是提升程序并发性能的关键。JAVA提供了丰富的线程API,包括...

    【Java课程设计】多任务下载器(进度条+断点续传).zip

    8. **设计模式**:为了保持代码的可维护性和扩展性,可以应用设计模式,如工厂模式用于创建线程,观察者模式用于更新进度条等UI组件,单例模式用于管理全局资源。 9. **用户界面**:虽然没有具体提到GUI,但实现一...

    毕业设计JAVA文件传输(论文+源代码).zip

    10. **源代码结构与设计模式**:一个良好的文件传输系统应该有清晰的架构,可能使用到的设计模式包括单例模式(用于服务器实例)、工厂模式(用于创建不同类型的连接)以及观察者模式(用于更新进度)等。...

    单文档多线程断点续传源码

    9. **代码结构与设计模式**:良好的代码组织和设计模式可以使代码更易于理解和维护。例如,可能会采用工厂模式创建线程,观察者模式更新进度,或者单例模式管理全局状态。 10. **测试与调试**:为了保证代码的正确...

    CS309-Object-Oriented-Programming:SUSTech课程CS309 OOP的个人回购

    CS309面向对象的程序设计SUSTech...Lab08:工厂设计模式Lab09:抽象工厂和单例设计模式Lab10:适配器设计模式Lab11:重构项目该项目由ICSE举办的软件工程学生竞赛提供SNA4Slack:Slack团队的网络分析和可视化回购: :

    [计算机项目]基于java的电子书下载系统设计与实现(项目报告+源代码+答辩PPT+数据库).zip

    项目可能运用了工厂模式、单例模式、策略模式等设计模式,以提高代码的可读性和可维护性。 5. **数据库设计** 数据库设计中,可能有用户表(User)、电子书表(Ebook)、分类表(Category)等,通过外键关联,...

    Android中高级面试必知必会.pdf

    设计模式(六大基本原则、项目中常用的设计模式、手写单例等).........120 13.断点续传.....134 14.Java 四大引用.........141 15.Java 的泛型146 16. final、finally、finalize 的区别 ........157 17.接口、抽象...

    高质量c++编程指南

    - 熟悉并应用常见的设计模式,如工厂模式、单例模式、观察者模式等,以解决特定的软件设计问题。 9. **测试**: - 编写单元测试以验证代码功能,确保修改不会破坏现有的功能。 - 使用持续集成工具自动化测试过程...

    基于java的开发源码-YOYOPlayer网络播放器源代码.zip

    9. **设计模式**:在大型项目中,良好的设计模式如工厂模式、观察者模式、单例模式等会贯穿整个代码,帮助提高代码的可维护性和可扩展性。 10. **调试和测试**:源代码中可能包含单元测试和集成测试,学习如何编写...

Global site tag (gtag.js) - Google Analytics