设计模式之单例模式

来源:互联网 发布:java程序设计竞赛 编辑:程序博客网 时间:2024/05/23 22:40

单例模式

   对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。   单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。   单例模式在全局范围内,同一个类只构造一个对象,全局范围可以引用。减少因对象创造、销毁带来的资源消耗。(项目中的应用:spring容器中所有的bean都是单例的),因为是单例,也就意味着只能多线程环境下使用,所以不得不考虑线程安全的问题,所以应该尽量避免使用类的实例变量,因为在单例的环境下,类的实例变量相当于静态变量保存在主存中,而主存中的变量是在所有线程之间共享的,所以在单例环境中应该尽量避免使用实例变量,单例环境中一定要用实例变量的话,只用实例变量来维护一些静态的资源(缓存功能,如xml资源等等)   单例模式三个要点:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。单例模式又名单件模式或单态模式。
<code class=" hljs cs" style="display: block; padding: 0.5em; color: rgb(0, 0, 0); font-family: 'Source Code Pro', monospace; outline: none !important; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">class</span> Singleton {    <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">static</span> Singleton singletone = <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">null</span>;    <span class="hljs-comment" style="color: rgb(136, 0, 0); outline: none !important;">//进行私有构造</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">private</span> <span class="hljs-title" style="outline: none !important;">Singleton</span>() {}    <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">static</span>  Singleton <span class="hljs-title" style="outline: none !important;">getInstance</span>() {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">if</span> (singletone == <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">null</span>) {            singletone = <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">new</span> OtherXiaoerSingleton();        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">return</span> singletone;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); outline: none !important;">public</span> synchronized String <span class="hljs-title" style="outline: none !important;">method</span>(){       <span class="hljs-comment" style="color: rgb(136, 0, 0); outline: none !important;">//具体的业务实现</span>    }}</code>

什么情况下使用单例?

(1)系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器,或者需要考虑资源消耗太大而只允许创建一个对象。 (2)客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。 (3)在一个系统中要求一个类只有一个实例时才应当使用单例模式。反过来,如果一个类可以有几个实例共存,就需要对单例模式进行改进,使之成为多例模式。

饿汉式单例和懒汉式单例

(1)饿汉式单例类在自己被加载时就将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。从速度和反应时间角度来讲,则比懒汉式单例类稍好些。(2)懒汉式单例类在实例化时,必须处理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费大量时间,这意味着出现多线程同时首次引用此类的机率变得较大,需要通过同步化机制进行控制

小结:

单例模式的主要优点在于提供了对唯一实例的受控访问并可以节约系统资源;其主要缺点在于因为缺少抽象层而难以扩展,且单例类职责过重,现在很多面向对象语言Java的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的共享对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致共享的单例对象状态的丢失。
0 0
原创粉丝点击