探索单例模式:设计模式中的瑰宝

文章目录

  • 常用的设计模式有以下几种:
    • [一.创建型模式(Creational Patterns):](#一.创建型模式(Creational Patterns):)
    • [二.结构型模式(Structural Patterns):](#二.结构型模式(Structural Patterns):)
    • [三.行为型模式(Behavioral Patterns):](#三.行为型模式(Behavioral Patterns):)
    • [四.并发模式(Concurrent Patterns):](#四.并发模式(Concurrent Patterns):)
  • 单例模式概念
  • [一、懒汉式(Lazy Initialization)示例:](#一、懒汉式(Lazy Initialization)示例:)
  • [二、饿汉式(Eager Initialization)示例:](#二、饿汉式(Eager Initialization)示例:)
  • 三、静态内部类示例(推荐使用):
  • 四、枚举示例(推荐使用):
  • 总结

常用的设计模式有以下几种:

一.创建型模式(Creational Patterns):

工厂模式(Factory Pattern)

抽象工厂模式(Abstract Factory Pattern)

单例模式(Singleton Pattern)

原型模式(Prototype Pattern)

建造者模式(Builder Pattern)

二.结构型模式(Structural Patterns):

适配器模式(Adapter Pattern)

桥接模式(Bridge Pattern)

装饰器模式(Decorator Pattern)

组合模式(Composite Pattern)

外观模式(Facade Pattern)

享元模式(Flyweight Pattern)

代理模式(Proxy Pattern)

三.行为型模式(Behavioral Patterns):

策略模式(Strategy Pattern)

观察者模式(Observer Pattern)

迭代器模式(Iterator Pattern)

命令模式(Command Pattern)

模板方法模式(Template Method Pattern)

职责链模式(Chain of Responsibility Pattern)

状态模式(State Pattern)

访问者模式(Visitor Pattern)

中介者模式(Mediator Pattern)

备忘录模式(Memento Pattern)

解释器模式(Interpreter Pattern)

四.并发模式(Concurrent Patterns):

单例模式(Singleton Pattern,在多线程环境下的应用)

生成器模式(Builder Pattern,在多线程环境下的应用)

保护性暂停模式(Guarded Suspension Pattern)

观察者模式(Observer Pattern,在多线程环境下的应用)

这些设计模式涵盖了对象的创建、对象间的组织和交互、以及对象的行为等方面,可以帮助开发者更好地组织和设计代码,提高代码的可扩展性、可维护性以及重用性。需要根据实际情况选择适合的设计模式来解决问题。


单例模式概念

单例模式是设计模式中的一种,旨在确保一个类只有一个实例对象,并提供全局访问点来获取该实例。

单例模式的关键要点如下😊😊😊:

1.私有构造函数:为了防止外部直接创建实例,将类的构造函数设为私有。

2.静态方法或静态变量:提供一个静态方法或静态变量来获取类的唯一实例。

3.延迟实例化或饿汉式初始化:根据需要可以选择延迟实例化或在类加载时就进行初始化。

4.线程安全性:需考虑在多线程环境下保证单例对象的创建和访问的线程安全性。

5.全局访问点:提供一个全局访问点,使得任何地方都可以获取到单例实例。

同时,单例模式也有一些注意点,如可能引起全局状态的问题、对单元测试的影响等,需要权衡利弊来选择适合的使用场景。😎😎😎

单例模式有以下几种常见的实现方法:😊😊😊

1.懒汉式(Lazy Initialization):

在第一次使用时才创建实例。
线程不安全,需要考虑多线程环境下的同步问题。
可以通过双重检查锁定、同步方法等方式来实现线程安全。

2.饿汉式(Eager Initialization):

在类加载时就创建实例。
线程安全,因为实例在类加载时就已经创建。
可能会导致不必要的资源浪费,因为实例在整个程序运行期间都存在,即使不使用也会被创建。

3.静态内部类:

使用静态内部类来持有单例实例,在第一次使用时才创建实例。
线程安全,因为静态内部类在类加载时只会被加载一次,保证了实例的唯一性。
推荐使用这种方式实现单例,因为代码简洁、线程安全,且支持懒加载。

4.枚举:

枚举常量就是单例对象的实例。
线程安全,且支持序列化和反序列化,以及防止反射攻击。
推荐使用这种方式实现单例,因为代码简洁、线程安全,且具有额外的优势。

一、懒汉式(Lazy Initialization)示例:

以下是一个懒汉式实现单例模式的示例(非线程安全版本):

java 复制代码
public class LazySingleton {
    private static LazySingleton instance;
    
    private LazySingleton() {
        // 私有的构造函数,防止外部实例化
    }
    
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
    
    // 其他方法...
}

在这个示例中,LazySingleton类的构造函数是私有的,不允许外部直接实例化对象。getInstance()方法是懒汉式的获取单例实例的方法。在第一次调用getInstance()时,会创建一个新的实例对象并将其赋值给instance变量。之后的调用都会返回之前创建的实例对象。

需要注意的是,这个示例是非线程安全的版本,多线程环境下可能会出现竞态条件。如果多个线程同时调用getInstance()方法,并且instance还没有被初始化,那么可能会创建多个实例。为了解决这个问题,可以使用同步机制(如双重检查锁定)来确保线程安全性。

下面是一个线程安全的双重检查锁定的示例:

java 复制代码
public class LazySingleton {
    private static volatile LazySingleton instance;
    
    private LazySingleton() {
        // 私有的构造函数,防止外部实例化
    }
    
    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
    
    // 其他方法...
}

在这个示例中,使用了双重检查锁定来确保线程安全。通过在synchronized块内进行二次判断,可以在多线程环境下保证只有一个实例被创建。

需要注意的是,上述示例虽然解决了线程安全性问题,但在某些情况下(如高并发场景)性能可能会有一定的影响。因此,在实际使用中可以根据需求权衡利弊来选择合适的实现方式。

二、饿汉式(Eager Initialization)示例:

以下是一个饿汉式实现单例模式的示例:

java 复制代码
public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();
    
    private EagerSingleton() {
        // 私有的构造函数,防止外部实例化
    }
    
    public static EagerSingleton getInstance() {
        return instance;
    }
    
    // 其他方法...
}

在这个示例中,EagerSingleton类在类加载时就创建了一个实例对象,并将其赋值给静态final的instance变量。getInstance()方法直接返回该实例,因此在任何时候调用getInstance()都会获取到同一个实例对象。

饿汉式的实现方式是在类加载时就进行实例化,因此可以保证线程安全性。由于实例在整个程序运行期间都会存在,可能会导致不必要的资源浪费。另外,需要注意的是,在某些特殊情况下可能会引起类加载的顺序问题,需要注意类加载的先后顺序。

总结来说,饿汉式是一种简单、线程安全的单例模式实现方式,适用于实例始终需要被创建且资源消耗较小的情况。但需要注意在某些特殊情况下可能引发的顺序问题。

三、静态内部类示例(推荐使用):

java 复制代码
public class Singleton {
    private Singleton() {
        // 私有的构造函数,防止外部实例化
    }
    
    private static class SingletonHolder {
        private static final Singleton instance = new Singleton();
    }
    
    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
    
    // 其他方法...
}

在这个示例中,Singleton类的实例被定义为私有的静态内部类SingletonHolder的静态成员变量。通过使用静态内部类的方式,可以实现懒加载和线程安全,而无需使用显式的同步机制。

四、枚举示例(推荐使用):

使用枚举实现单例具有以下优点:

线程安全:枚举常量的创建是线程安全的,不会被多个线程重复创建。

防止序列化和反射攻击:枚举类默认实现了Serializable接口,使用枚举实现的单例对象在序列化和反序列化时会得到正确的结果。同时,由于枚举常量有固定的实例,不会受到反射攻击。

以下是使用枚举实现单例的示例:

java 复制代码
public enum Singleton {
    INSTANCE;
    
    public void doSomething() {
        // 单例对象的方法
    }
}

在这个示例中,Singleton是一个枚举类型,并且定义了一个名为INSTANCE的枚举常量,它是单例对象的唯一实例。可以通过Singleton.INSTANCE来访问这个单例对象,并调用其方法。

使用枚举实现单例模式简洁且安全,不需要担心线程安全和反射攻击的问题。因此,当需要实现单例时,可以优先考虑使用枚举来实现。

总结

单例模式的应用有很多,例如全局资源管理、日志记录器、数据库连接池、配置管理器等。

它可以简化代码,提高资源的利用效率,并确保全局只有一个实例对象。😎😎😎

@作者:加辣椒了吗?

简介:憨批大学生一枚,喜欢在博客上记录自己的学习心得,也希望能够帮助到你们!

相关推荐
Daniel 大东17 分钟前
idea 解决缓存损坏问题
java·缓存·intellij-idea
wind瑞23 分钟前
IntelliJ IDEA插件开发-代码补全插件入门开发
java·ide·intellij-idea
HappyAcmen24 分钟前
IDEA部署AI代写插件
java·人工智能·intellij-idea
马剑威(威哥爱编程)29 分钟前
读写锁分离设计模式详解
java·设计模式·java-ee
鸽鸽程序猿30 分钟前
【算法】【优选算法】前缀和(上)
java·算法·前缀和
修道-032330 分钟前
【JAVA】二、设计模式之策略模式
java·设计模式·策略模式
九圣残炎36 分钟前
【从零开始的LeetCode-算法】2559. 统计范围内的元音字符串数
java·算法·leetcode
当归10241 小时前
若依项目-结构解读
java
hlsd#1 小时前
关于 SpringBoot 时间处理的总结
java·spring boot·后端
iiiiiankor1 小时前
C/C++内存管理 | new的机制 | 重载自己的operator new
java·c语言·c++