千家信息网

如何理解Java设计模式的单例模式

发表于:2025-11-13 作者:千家信息网编辑
千家信息网最后更新 2025年11月13日,这篇文章主要讲解了"如何理解Java设计模式的单例模式",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何理解Java设计模式的单例模式"吧!一、什么是
千家信息网最后更新 2025年11月13日如何理解Java设计模式的单例模式

这篇文章主要讲解了"如何理解Java设计模式的单例模式",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何理解Java设计模式的单例模式"吧!

    一、什么是单例模式

    单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。

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

    单例的实现主要是通过以下两个步骤:

    1.将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;

    2.在该类内提供一个静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。

    二、单例模式的应用场景

    举一个小例子,在我们的windows桌面上,我们打开了一个回收站,当我们试图再次打开一个新的回收站时,Windows系统并不会为你弹出一个新的回收站窗口。,也就是说在整个系统运行的过程中,系统只维护一个回收站的实例。这就是一个典型的单例模式运用。

    继续说回收站,我们在实际使用中并不存在需要同时打开两个回收站窗口的必要性。假如我每次创建回收站时都需要消耗大量的资源,而每个回收站之间资源是共享的,那么在没有必要多次重复创建该实例的情况下,创建了多个实例,这样做就会给系统造成不必要的负担,造成资源浪费。

    再举一个例子,网站的计数器,一般也是采用单例模式实现,如果你存在多个计数器,每一个用户的访问都刷新计数器的值,这样的话你的实计数的值是难以同步的。但是如果采用单例模式实现就不会存在这样的问题,而且还可以避免线程安全问题。同样多线程的线程池的设计一般也是采用单例模式,这是由于线程池需要方便对池中的线程进行控制

    同样,对于一些应用程序的日志应用,或者web开发中读取配置文件都适合使用单例模式,如HttpApplication 就是单例的典型应用。

    从上述的例子中我们可以总结出适合使用单例模式的场景和优缺点:

    适用场景:

    1.需要生成唯一序列的环境

    2.需要频繁实例化然后销毁的对象。

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

    4.方便资源相互通信的环境

    三、单例模式的优缺点

    优点:

    • 在内存中只有一个对象,节省内存空间;

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

    • 避免对共享资源的多重占用,简化访问;

    • 为整个系统提供一个全局访问点。

    缺点:

    • 不适用于变化频繁的对象;

    • 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;

    • 如果实例化的对象长时间不被利用,系统会认为该对象是垃圾而被回收,这可能会导致对象状态的丢失;

    四、单例模式的实现

    1.饿汉式

    // 饿汉式单例public class Singleton1 {     // 指向自己实例的私有静态引用,主动创建    private static Singleton1 singleton1 = new Singleton1();     // 私有的构造方法    private Singleton1(){}     // 以自己实例为返回值的静态的公有方法,静态工厂方法    public static Singleton1 getSingleton1(){        return singleton1;    }}

    我们知道,类加载的方式是按需加载,且加载一次。。因此,在上述单例类被加载时,就会实例化一个对象并交给自己的引用,供系统使用;而且,由于这个类在整个生命周期中只会被加载一次,因此只会创建一个实例,即能够充分保证单例。

    优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。

    缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。

    2.懒汉式

    // 懒汉式单例public class Singleton2 {     // 指向自己实例的私有静态引用    private static Singleton2 singleton2;     // 私有的构造方法    private Singleton2(){}     // 以自己实例为返回值的静态的公有方法,静态工厂方法    public static Singleton2 getSingleton2(){        // 被动创建,在真正需要使用时才去创建        if (singleton2 == null) {            singleton2 = new Singleton2();        }        return singleton2;    }}

    我们从懒汉式单例可以看到,单例实例被延迟加载,即只有在真正使用的时候才会实例化一个对象并交给自己的引用。

    这种写法起到了Lazy Loading的效果,但是只能在单线程下使用。如果在多线程下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可使用这种方式。

    3.双重加锁机制

    public class Singleton    {        private static Singleton instance;        //程序运行时创建一个静态只读的进程辅助对象        private static readonly object syncRoot = new object();        private Singleton() { }        public static Singleton GetInstance()        {            //先判断是否存在,不存在再加锁处理            if (instance == null)            {                //在同一个时刻加了锁的那部分程序只有一个线程可以进入                lock (syncRoot)                {                    if (instance == null)                    {                        instance = new Singleton();                    }                }            }            return instance;        }    }

    Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,我们进行了两次if (singleton == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if (singleton == null),直接return实例化对象。

    使用双重检测同步延迟加载去创建单例的做法是一个非常优秀的做法,其不但保证了单例,而且切实提高了程序运行效率

    优点:线程安全;延迟加载;效率较高。

    4.静态初始化

    //阻止发生派生,而派生可能会增加实例    public sealed class Singleton    {        //在第一次引用类的任何成员时创建实例,公共语言运行库负责处理变量初始化        private static readonly Singleton instance=new Singleton();         private Singleton() { }        public static Singleton GetInstance()        {            return instance;        }    }

    在实际应用中,C#与公共语言运行库也提供了一种"静态初始化"方法,这种方法不需要开发人员显式地编写线程安全代码,即可解决多线程环境下它是不安全的问题。

    感谢各位的阅读,以上就是"如何理解Java设计模式的单例模式"的内容了,经过本文的学习后,相信大家对如何理解Java设计模式的单例模式这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

    实例 对象 模式 线程 方法 静态 系统 回收站 设计 程序 资源 问题 设计模式 安全 环境 应用 私有 运行 配置 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发一年得多少钱 大连网络安全生产项目 江苏博浪互联网科技有限公司 广西手机软件开发方案 盗服务器源码 对不起服务器需要维护怎么解决 开封市网络安全和信息化委员会 网络安全的历程 wow 修改默认服务器 软件开发团队 建设 查询会员姓名的数据库语句 桂林搞软件开发的哪里 惠州网络安全海报 微创软件数据库测试 游戏服务器登录超时是怎么回事 全方位网络安全解决方案 宝山区自动软件开发产品介绍 输入网络安全性金轮什么意思 网络安全方面主题班会300字 bcp按条件导出数据库 sql 取 随机数据库 网络安全与国防教育的影响 网络技术安全发展现状和趋势 汕头地产软件开发报价 新港开发区智慧园招聘软件开发吗 黄河鲲鹏服务器和台式机生产线 中国生物文献数据库在哪里注册 java调用扫描仪传输服务器端 服务器路线代表什么意思 一家软件开发公司的生存
    0