前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java设计模式详解----单例模式

Java设计模式详解----单例模式

作者头像
ma布
发布2024-10-30 08:48:50
1080
发布2024-10-30 08:48:50
举报
文章被收录于专栏:Java开发

前言:软件设计模式( Software Design Pattern ),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案。也就是说,它是解决特定问题的一系列套路,是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。

正确使用设计模式具有以下优点。

1.可以提高程序员的思维能力、编程能力和设计能力。

2.使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,

从而缩短软件的开发周期。

3.使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。

设计模式主要可以分为以下三大类:创建型模式,结构型模式,行为型模式

因此本篇文章主要是讲解第一类设计模式之创建型模式之单例模式

1:什么是单例模式

保证一个类只有一个实例,并且提供一个访问该全局访问点

3:单例模式的优缺点

优点:

1. 在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就防止其它对象对自己的实例化,确保所有的对象都访问一个实例 2. 单例模式具有一定的伸缩性,类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。 3. 提供了对唯一实例的受控访问。 4. 由于在系统内存中只存在一个对象,因此可以节约系统资源,当需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能。 5. 允许可变数目的实例。 6. 避免对共享资源的多重占用。

缺点:

1. 不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。 2. 由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。 3. 单例类的职责过重,在一定程度上违背了 “ 单一职责原则 ” 。 4. 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。

3:单例模式的应用场景

1. 网站的计数器,一般也是采用单例模式实现,否则难以同步。 2. 应用程序的日志应用,一般都是单例模式实现,只有一个实例去操作才好,否则内容不好追加显示。 3. 多线程的线程池的设计一般也是采用单例模式,因为线程池要方便对池中的线程进行控制 4. Windows 的(任务管理器)就是很典型的单例模式,他不能打开俩个 5. windows 的(回收站)也是典型的单例应用。在整个系统运行过程中,回收站只维护一个实例。

4:单例模式的分类

1. 饿汉式: 类初始化时 , 会立即加载该对象,线程天生安全 , 调用效率高。 2. 懒汉式 : 类初始化时 , 不会初始化该对象 , 真正需要使用的时候才会创建该对象 , 具备懒加载功能。 3. 静态内部方式 : 结合了懒汉式和饿汉式各自的优点,真正需要对象的时候才会加载,加载类是线程安全的。 4. 枚举单例 : 使用枚举实现单例模式 优点 : 实现简单、调用效率高,枚举本身就是单例,由 jvm 从根本上提供保障! 避免通过反射和反序列化的漏洞, 缺点没有延迟加载。 5. 双重检测锁方式 ( 因为 JVM 本质重排序的原因,可能会初始化多次,不推荐使用 )

4.1:饿汉式

饿汉式 : 类初始化时 , 会立即加载该对象,线程天生安全 , 调用效率高。

代码语言:javascript
复制
/**
 * @author: dlwlrma
 * @data 2024年10月26日 19:50
 * @Description: TODO:单例模式之饿汉式
 */

public class Demo1 {
    //饿汉式,类初始化时,会立即创建对象,调用效率高,但可能会造成内存的浪费
    private static Demo1 demo1=new Demo1();
    private Demo1(){

    }
    public static Demo1 getInstance(){
        return demo1;
    }
    public static void main(String[] args) {
        Demo1 demo11=Demo1.getInstance();
        Demo1 demo12=Demo1.getInstance();
        System.out.println(demo11==demo12);
    }
}

4.2:懒汉式

1. 懒汉式 : 类初始化时 , 不会初始化该对象 , 真正需要使用的时候才会创建该对象 , 具备懒加载功能。

代码语言:javascript
复制
/**
 * @author: dlwlrma
 * @data 2024年10月26日 19:52
 * @Description: TODO:单例模式之懒汉式
 */
//懒汉式
public class Demo2 {
    //类初始化时,不会初始化该对象,真正需要使用的时候才会创建该对象。
    private static Demo2 demo2;
    private Demo2() {
        System.out.println("私有Demo2构造参数初始化");
    }
    public synchronized static Demo2 getInstance() {
        if (demo2 == null) {
            demo2 = new Demo2();
        }
        return demo2;
    }
    public static void main(String[] args) {
        Demo2 s1 = Demo2.getInstance();
        Demo2 s2 = Demo2.getInstance();
        System.out.println(s1 == s2);
    }
}

4.3:静态内部式

1. 静态内部方式 : 结合了懒汉式和饿汉式各自的优点,真正需要对象的时候才会加载,加载类是线程安全的。

代码语言:javascript
复制
/**
 * 静态内部类方式
 * @author dlwlrma
 * @date 2024/10/26 19:56
 * @return null
 */
public class Demo3 {
    private Demo3() {
        System.out.println("私有Demo3构造参数初始化");
    }
    public static class SingletonClassInstance {
        private static final Demo3 DEMO_3 = new Demo3();
    }
    // 方法没有同步
    public static Demo3 getInstance() {
        return SingletonClassInstance.DEMO_3;
    }
    public static void main(String[] args) {
        Demo3 s1 = Demo3.getInstance();
        Demo3 s2 = Demo3.getInstance();
        System.out.println(s1 == s2);
    }
}

4.4:枚举单例式

1. 枚举单例 : 使用枚举实现单例模式 优点 : 实现简单、调用效率高,枚举本身就是单例,由 jvm 从根本上提供保障! 避免通过反射和反序列化的漏洞, 缺点没有延迟加载。

代码语言:javascript
复制
/**
 * @author: dlwlrma
 * @data 2024年10月26日 19:57
 * @Description: TODO: 使用枚举实现单例模式 优点:实现简单、枚举本身就是单例,由jvm从根本上提供 
                       保障!避免通过反射和反序列化的漏洞 缺点没有延迟加载
 */
public class Demo4 {
    public static Demo4 getInstance() {
        return Demo.INSTANCE.getInstance();
    }
    public static void main(String[] args) {
        Demo4 s1 = Demo4.getInstance();
        Demo4 s2 = Demo4.getInstance();
        System.out.println(s1 == s2);
    }
    //定义枚举
    private static enum Demo {
        INSTANCE;
        // 枚举元素为单例
        private Demo4 demo4;
        private Demo() {
            System.out.println("枚举Demo私有构造参数");
            demo4 = new Demo4();
        }
        
        public Demo4 getInstance() {
            return demo4;
        }
    }
}

4.5:双重检测锁式

1. 双重检测锁方式 ( 因为 JVM 本质重排序的原因,可能会初始化多次,不推荐使用 )

代码语言:javascript
复制
/**
 * @author: dlwlrma
 * @data 2024年10月26日 19:59
 * @Description: TODO:双重检测锁方式
 */
//双重检测锁方式
public class Demo5 {
    private static Demo5 demo5;
    private Demo5() {
        System.out.println("私有Demo4构造参数初始化");
    }
    public static Demo5 getInstance() {
        if (demo5 == null) {
            synchronized (Demo5.class) {
                if (demo5 == null) {
                    demo5 = new Demo5();
                }
            }
        }
        return demo5;
    }
    public static void main(String[] args) {
        Demo5 s1 = Demo5.getInstance();
        Demo5 s2 = Demo5.getInstance();
        System.out.println(s1 == s2);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1:什么是单例模式
  • 3:单例模式的优缺点
  • 3:单例模式的应用场景
  • 4:单例模式的分类
    • 4.1:饿汉式
      • 4.2:懒汉式
        • 4.3:静态内部式
          • 4.4:枚举单例式
            • 4.5:双重检测锁式
            相关产品与服务
            数据库
            云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档