ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java设计模式-单例模式(四)

2019-09-11 17:04:20  阅读:178  来源: 互联网

标签:java getInstance instance 实例 static 单例 设计模式 加载


单例顾名思义只能有单一的实例,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为

使用场景:如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取;还有如数据库连接池也是采用单例模式,只有一个连接池就可以了,再多就是浪费系统资源;还有如spring中的bean默认是单例;线程池;

单例的优点:
1.在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就 防止其它对象对自己的实例化,确保所有的对象都访问一个实例
2.提供了对唯一实例的受控访问
3.由于在系统内存中只存在一个对象,因此可以 节约系统资源,当 需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能
4.避免对共享资源的多重占用
单例的缺点:
1.由于单利模式中没有抽象层,因此单例类的扩展有很大的困难
2.滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。
实现单利模式的原则:
a.私有构造方法
b.私有静态引用指向自己实例
c.以自己实例为返回值的公有静态方法

饿汉式:单例实例在类装载时就构建,急切初始化

public class SingleOne {
    /**私有化构造方法*/
    private SingleOne(){}
    /**类加载就实例化,私有静态引用指向自己实例 */
    private static SingleOne instance = new SingleOne();
    /**以自己实例为返回值的公有静态方法*/
    public static SingleOne getInstance(){
        return instance;
    }
}

验证是否是单例:发现内存地址值是一样,说明多次获取是一个实例对象。
在这里插入图片描述
优点
1.线程安全
2.在类加载的同时已经创建好一个静态对象,调用时反应速度快
缺点 : 资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化 。


懒汉式:单例实例在第一次被使用时构建,延迟初始化。

public class SingleTwo {
    /**私有化构造方法*/
    private SingleTwo(){}
    /**私有静态引用指向自己实例 */
    private static SingleTwo instance = null;
    /**以自己实例为返回值的公有静态方法*/
    public static SingleTwo getInstance(){
        //多个线程判断instance都为null时,在执行new操作时多线程会出现重复情况
        /*if(instance == null){
            instance = new SingleTwo();
        }*/

        //==============================
        //双重检查,防止多线程时创建多个实例
        if(instance == null){
            synchronized (SingleTwo.class){
                if(instance == null){
                    instance = new SingleTwo();
                }
            }
        }
        return instance;
    }
}

优点:资源利用率高,不执行getInstance()不被实例,
缺点:一次加载时反应不够快
懒汉式的另一种实现方法:

public class SingleThree {
    /**私有化构造方法*/
    private SingleThree(){}
    
    /**内部类*/
    private static class SingleThreeHelp{
        static SingleThree instance = new SingleThree();
    }
    /**以自己实例为返回值的公有静态方法*/
    public static SingleThree getInstance(){
        return SingleThreeHelp.instance;
    }
}

静态内部类的优点是:外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化instance,故而不占内存。即当SingleThree 第一次被加载时,并不需要去加载SingleThreeHelp,只有当getInstance()方法第一次被调用时,才会去初始化instance,第一次调用getInstance()方法会导致虚拟机加载SingleThreeHelp类,这种方法不仅能确保线程安全,也能保证单例的唯一性,同时也延迟了单例的实例化。

所以要根据自己的实际场景来确定使用懒汉式还是饿汉式
总结: 一般采用饿汉式,若对资源十分在意可以采用静态内部类,不建议采用懒汉式及双重检测
参考 https://blog.csdn.net/mnb65482/article/details/80458571

标签:java,getInstance,instance,实例,static,单例,设计模式,加载
来源: https://blog.csdn.net/u010509052/article/details/100736483

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有