Java语言之23种设计模式(1)-单例模式
龚超 2018-04-25 来源 : 阅读 1064 评论 0

摘要:Java语言的单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。希望通过下面的介绍能让大家对Java语言的单例模式有更深的了解。

定义:

        单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。


特点:

       1、单例类只能有一个实例。
  2、单例类必须自己自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例


单例模式的要点:

    1,私有的构造方法

    2,指向自己实例的私有静态引用

    3,以自己实例为返回值的静态的公有的方法


单例模式根据实例化对象时机的不同分为两种:

        一种是饿汉式单例,一种是懒汉式单例。

        饿汉式单例在单例类被加载时候,就实例化一个对象交给自己的引用;而懒汉式在调用取得实例方法的时候才会实例化对象。

代码如下:

饿汉式单例

public class Singleton {  
    private static Singleton singleton = new Singleton();  
    private Singleton(){}  
    public static Singleton getInstance(){  
        return singleton;  
    }  
}

懒汉式单例

public class Singleton {  
    private static Singleton singleton;  
    private Singleton(){}  
    public static synchronized Singleton getInstance(){  
        if(singleton==null){  
            singleton = new Singleton();  
        }  
        return singleton;  
    }  
}

单例模式还有一种比较常见的形式:双重锁的形式

public class Singleton{    
    private static volatile Singleton instance=null;    
    private Singleton(){        
    //do something
    }    
    public static  Singleton getInstance(){        
        if(instance==null){            
            synchronized(SingletonClass.class){                
                if(instance==null){
                    instance=new Singleton();
                }
            }
        }        
    return instance;
     }
}

 这个模式将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。

        这种模式中双重判断加同步的方式,比第一个例子中的效率大大提升,因为如果单层if判断,在服务器允许的情况下,假设有一百个线程,耗费的时间为100*(同步判断时间+if判断时间),而如果双重if判断,100的线程可以同时if判断,理论消耗的时间只有一个if判断的时间。

        所以如果面对高并发的情况,而且采用的是懒汉模式,最好的选择就是双重判断加同步的方式。


单例模式的优点:

    1,在内存中只有一个对象,节省内存空间。

    2,避免频繁的创建销毁对象,可以提高性能。

    3,避免对共享资源的多重占用。

    4,可以全局访问。


单例模式的优点:

    1,扩展困难,由于getInstance静态函数没有办法生成子类的实例。如果要拓展,只有重写那个类。

    2,隐式使用引起类结构不清晰。

    3,导致程序内存泄露的问题。


适用场景:

        由于单例模式的以上优点,所以是编程中用的比较多的一种设计模式。以下为使用单例模式的场景:

        1,需要频繁实例化然后销毁的对象。

        2,创建对象时耗时过多或者耗资源过多,但又经常用到的对象。

        3,资源共享的情况下,避免由于资源操作时导致的性能或损耗等

        4,控制资源的情况下,方便资源之间的互相通信。


单例模式注意事项:

        只能使用单例类提供的方法得到单例对象,不要使用反射,否则将会实例化一个新对象。

        不要做断开单例类对象与类中静态引用的危险操作。

        多线程使用单例使用共享资源时,注意线程安全问题。


关于Java中单例模式的一些常见问题:


单例模式的对象长时间不用会被jvm垃圾收集器收集吗

        除非人为地断开单例中静态引用到单例对象的联接,否则jvm垃圾收集器是不会回收单例对象的。

jvm卸载类的判定条件如下:

        1,该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。

        2,加载该类的ClassLoader已经被回收。

        3,该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

        只有三个条件都满足,jvm才会在垃圾收集的时候卸载类。显然,单例的类不满足条件一,因此单例类也不会被回收。


在一个jvm中会出现多个单例吗

        在分布式系统、多个类加载器、以及序列化的的情况下,会产生多个单例,这一点是无庸置疑的。那么在同一个jvm中,会不会产生单例呢?使用单例提供的getInstance()方法只能得到同一个单例,除非是使用反射方式,将会得到新的单例。

代码如下:

Class c = Class.forName(Singleton.class.getName());  
Constructor ct = c.getDeclaredConstructor();  
ct.setAccessible(true);  
Singleton singleton = (Singleton)ct.newInstance();

这样,每次运行都会产生新的单例对象。所以运用单例模式时,一定注意不要使用反射产生新的单例对象。

 

在getInstance()方法上同步有优势还是仅同步必要的块更优优势?

        因为锁定仅仅在创建实例时才有意义,然后其他时候实例仅仅是只读访问的,因此只同步必要的块的性能更优,并且是更好的选择。

        缺点:只有在第一次调用的时候,才会出现生成2个对象,才必须要求同步。而一旦singleton 不为null,系统依旧花费同步锁开销,有点得不偿失。


单例类可以被继承吗

        根据单例实例构造的时机和方式不同,单例模式还可以分成几种。但对于这种通过私有化构造函数,静态方法提供实例的单例类而言,是不支持继承的。

        这种模式的单例实现要求每个具体的单例类自身来维护单例实例和限制多个实例的生成。但可以采用另外一种实现单例的思路:登记式单例,来使得单例对继承开放。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言Java频道!

本文由 @职坐标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论
本文作者 联系TA

擅长针对企业软件开发的产品设计及开发的细节与流程设计课程内容。座右铭:大道至简!

  • 370
    文章
  • 45133
    人气
  • 83%
    受欢迎度

已有24人表明态度,83%喜欢该老师!

进入TA的空间
求职秘籍 直通车
  • 资料领取 资料领取 资料领取
  • 答疑解惑 答疑解惑 答疑解惑
  • 技术交流 技术交流 技术交流
  • 职业测评 职业测评 职业测评
  • 面试技巧 面试技巧 面试技巧
  • 高薪秘笈 高薪秘笈 高薪秘笈
TA的其他文章 更多>>
WEB前端必须会的基本知识题目
经验技巧 93% 的用户喜欢
Java语言中四种遍历List的方法总结(推荐)
经验技巧 91% 的用户喜欢
Java语言之SHA-256加密的两种实现方法详解
经验技巧 75% 的用户喜欢
java语言实现把两个有序数组合并到一个数组的实例
经验技巧 75% 的用户喜欢
通过Java语言代码来创建view的方法
经验技巧 80% 的用户喜欢
其他海同师资 更多>>
吕益平
吕益平 联系TA
熟悉企业软件开发的产品设计及开发
孔庆琦
孔庆琦 联系TA
对MVC模式和三层架构有深入的研究
戴懿颢​
戴懿颢​ 联系TA
20年+嵌入式开发经验,精多语言 / 云 / 安全 / 数据库
郭自琦
郭自琦 联系TA
16年物联网经验,涉多项目,多校授课,出版书籍并研发IT教程
余承民
余承民 联系TA
8年开发+5年教学经验,指导数千名学员高薪就业
经验技巧30天热搜词 更多>>

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved