【设计模式】单例模式

简介: 设计模式单例模式单例模式(Singleton Pattern)是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。
img_a2c517c88581d62612a25018678f05fd.png
设计模式

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。

  1. 某个类只能有一个实例。
  2. 它必须自行创建这个实例。
  3. 它必须自行向整个系统提供这个实例。

单例模式关键点:

  • 构造函数私有化(不让外部创建此类对象)。
  • 通过一个静态方法或枚举返回单例类对象。
  • 多线程环境下,确保单例(难点)。
  • 反序列化不会重新构建对象。

饿汉式

public class Singleton {
    // 单例对象
    private final static Singleton INSTANCE = new Singleton();

    // 或
    // private final static Singleton INSTANCE;
    // static {
    // INSTANCE = new Singleton();
    // }

    // 私有构造方法
    private Singleton() {
    }

    // 公有静态方法用于获取单例对象
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

线程安全。但是没使用它时,就已经建立了对象,开销内存。

懒汉式

public class Singleton {
    // 单例对象
    private static Singleton INSTANCE = null;

    // 私有构造方法
    private Singleton() {
    }

    // synchronized关键字修饰静态方法
    public static synchronized Singleton getInstance() {
        if (null == INSTANCE) {// 空值判断
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}

在第一次调用getInstance()时,创建单例对象。synchronized关键字修饰,使getInstance()是一个同步方法。保证多线程情况下单例对象的唯一。但是,同步会耗费资源。

双检锁式(Double Check Lock(DCL))

public class Singleton {
    // 单例对象,volatile关键字保证INSTANCE的原子性
    private volatile static Singleton INSTANCE = null;

    // 私有构造方法
    private Singleton() {
    }

    // 两次空值检查,synchronized关键字同步
    public static Singleton getInstance() {
        if (null == INSTANCE) {
            synchronized (Singleton.class) {
                if (null == INSTANCE) {
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
}

语句INSTANCE = new Singleton();在编译时的步骤如下:

  1. 给Singleton的实例分配内存。
  2. 调用Singleton()的构造函数,初始化成员字段。
  3. 将INSTANCE 对象指向分配的内存空间(此时对象非空)。

Java编译器允许处理器乱序执行。上诉的2,3两步的顺序可能被打乱。打乱后,非空判断的线程不安全。在JDK1.5之后,调整了JVM,具体化了volatile关键字,表示此操作是一个原子操作,不能中间被分割执行。使用volatile关键字会影响性能。

静态内部类

public class Singleton {
    // 内部类,包含单例的对象
    private static class SingletonHolder {
        public static final Singleton INSTANCE = new Singleton();
    }

    // 私有构造方法
    private Singleton() {
    }

    // 公有静态方法用于获取单例对象
    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

第一次加载Singleton时,SingletonHolder不会被加载。只用调用getInstance()时,才加载SingletonHolder,并创建INSTANCE推荐大家使用

枚举式

public enum SingletonEnum {
    INSTANCE;
}

虽说代码简单,enum的实质也是class(编译时,会先翻译成一个class)。优点是反序列化也不会重新生成新的实例。

前几种方式,如果要避免反序列化也不会重新生成新的实例。需要重写:

private Object readResolve() throws ObjectStreamException{
    return INSTANCE;
}

单例管理类

一个程序可能有多个单例对象。先建立一个上诉管理类。

public class SingletonManager {
    // 容器
    private static Map<String, Object> objMap = new HashMap<String, Object>();

    // 私有构造方法
    private SingletonManager() {
    }

    // 注册单例
    public static void ascendSingleton(String key, Object instance) {
        if (!objMap.containsKey(key)) {
            objMap.put(key, instance);
        }
    }

    // 获得单例对象
    public static Object getInstance(String key) {
        return objMap.get(key);
    }
}

通过注册,可以管理多种类型的单例,使用统一接口,隐藏具体实现。
使用时:

//注册单例
SingletonManager.ascendSingleton("SingletonKey",Singleton.getInstance());
//获得单例对象
Singleton singleton = SingletonManager.getInstance("SingletonKey");

优点

  • 只有一个对象,全局使用。
  • 只需要建立一次,占一个内存,节约资源。

缺点

  • 没有接口,难以扩展。
  • 生命周期长,如果引用短生命周期对象会内存泄漏。

补充

通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。

附件

设计模式Demo
GitHub源码:https://github.com/wzmyyj/Design-Pattern

目录
相关文章
|
2月前
|
设计模式 存储 SQL
PHP中的设计模式:单例模式的探索
在PHP开发中,单例模式是一种常用的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。本文将通过一个简单的例子,逐步引导你理解如何在PHP中实现和利用单例模式,以及它在实际项目中的应用价值。
|
4月前
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
49 4
|
8天前
|
设计模式 存储 安全
PHP中的设计模式:单例模式深度解析
在软件开发的广袤天地中,设计模式如同璀璨星辰,指引着程序员们解决复杂问题的方向。其中,单例模式以其独特的魅力,确保了一个类仅有一个实例,并提供了一个访问它的全局访问点,成为众多项目中不可或缺的设计智慧。本文旨在深入探讨PHP中单例模式的实现方式、应用场景及背后的哲理,引导读者思考其在现代软件架构中的重要性与运用策略。
23 5
|
13天前
|
设计模式 安全 Java
Java 编程中的设计模式:单例模式的深度解析
【9月更文挑战第22天】在Java的世界里,单例模式就像是一位老练的舞者,轻盈地穿梭在对象创建的舞台上。它确保了一个类仅有一个实例,并提供全局访问点。这不仅仅是代码优雅的体现,更是资源管理的高手。我们将一起探索单例模式的奥秘,从基础实现到高级应用,再到它与现代Java版本的舞蹈,让我们揭开单例模式的面纱,一探究竟。
23 11
|
9天前
|
设计模式 存储 缓存
PHP中的设计模式:单例模式的深入解析
在PHP开发中,设计模式是提高代码可维护性、扩展性和重用性的关键技术之一。本文将深入探讨PHP中的单例模式,包括其定义、实现方式、应用场景以及优缺点。通过对单例模式的全面剖析,帮助开发者更好地理解和应用这一设计模式,从而编写出更加高效和优雅的PHP代码。
|
9天前
|
设计模式 安全 Java
设计模式--单例模式Singleton
这篇文章详细介绍了单例模式Singleton的八种实现方式,包括饿汉式(静态常量和静态代码块)、懒汉式(线程不安全和线程安全的同步方法、同步代码块)、双重检查、静态内部类和枚举。每种方式都有详细的代码示例和优缺点说明,帮助理解单例模式的应用和选择适合的实现方法。
设计模式--单例模式Singleton
|
11天前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
|
13天前
|
设计模式 数据库连接 PHP
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发中,设计模式是提高代码可维护性、扩展性和复用性的关键技术之一。本文将深入探讨单例模式——一种确保类只有一个实例,并提供该实例的全局访问点的设计模式。我们将从单例模式的基本概念入手,剖析其在PHP中的应用方式,并通过实际案例展示如何在不同场景下有效利用单例模式来优化应用架构。
|
2月前
|
设计模式 存储 负载均衡
【五】设计模式~~~创建型模式~~~单例模式(Java)
文章详细介绍了单例模式(Singleton Pattern),这是一种确保一个类只有一个实例,并提供全局访问点的设计模式。文中通过Windows任务管理器的例子阐述了单例模式的动机,解释了如何通过私有构造函数、静态私有成员变量和公有静态方法实现单例模式。接着,通过负载均衡器的案例展示了单例模式的应用,并讨论了单例模式的优点、缺点以及适用场景。最后,文章还探讨了饿汉式和懒汉式单例的实现方式及其比较。
【五】设计模式~~~创建型模式~~~单例模式(Java)
|
10天前
|
设计模式 Java 安全
Java设计模式-单例模式(2)
Java设计模式-单例模式(2)