首页 > 其他分享 >六、设计模式-6.1、单例模式

六、设计模式-6.1、单例模式

时间:2024-09-26 21:51:02浏览次数:9  
标签:Singleton 单例 创建 instance 实例 线程 6.1 设计模式

6.1、单例模式

6.1.1、在Java中实现单例模式有哪些方法?

答:
在Java中,实现单例模式的常用方法有以下几种:

  1. 饿汉式单例模式:在类加载时就创建一个实例,并提供一个公共的静态方法获取实例。代码示例:
public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}
  1. 懒汉式单例模式(线程安全):在第一次调用获取实例的方法时创建实例,保证只有一个实例被创建。代码示例:
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  1. 懒汉式单例模式(双重检查锁定):使用双重检查锁定来保证线程安全和性能。代码示例:
public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
  1. 静态内部类单例模式(线程安全):利用类加载的特性实现线程安全的懒加载。代码示例:
public class Singleton {
    private Singleton() {}

    private static class SingletonHolder {
        private static final Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}
  1. 枚举单例模式:使用枚举类型来实现单例模式,枚举类型的实例只能被实例化一次。代码示例:
public enum Singleton {
    INSTANCE;

    // 可以添加其他方法和属性
}

6.1.2、哪些情况下的单例对象可能会被破坏?

答:

  1. 多线程环境下的并发访问:如果多个线程同时调用getInstance()方法,可能会导致创建多个实例。
  2. 反射:通过反射机制可以访问私有构造方法,从而创建多个实例。
  3. 序列化和反序列化:如果单例类实现了Serializable接口,那么对象可以被序列化和反序列化,从而创建多个实例。
  4. 类加载器的不同:如果使用不同的类加载器加载同一个单例类,会创建多个实例。

6.1.3、在DCL单例写法中,为什么主要做两次检查?

答:
在DCL(Double-Checked Locking)单例写法中,主要进行两次检查是为了在高并发环境下确保线程安全性。假设只进行一次检查,那么在多线程环境下,可能会出现多个线程同时通过第一次检查,然后同时进入同步代码块,创建多个实例对象。

通过进行两次检查,可以避免这种情况发生。第一次检查主要是为了避免不必要的同步开销,只有当实例对象为空时,才需要进一步进行同步。第二次检查主要是为了避免在一个线程创建完实例对象后,另一个线程在获取锁之前进入同步代码块,从而避免重复创建实例对象。

因此,通过进行两次检查,可以在高并发环境下保证只有一个线程能够创建实例对象,从而实现线程安全的单例模式。

6.1.4、哪些情景不适合使用单例模式?

答:

  1. 需要使用多个不同实例的情景:单例模式只能创建一个实例,如果需要使用多个不同实例,就不适合使用单例模式。

  2. 对象的生命周期需要动态控制的情景:单例模式创建的实例一般在程序启动时就被创建,而且在整个程序运行期间都存在。如果需要根据运行时的条件来创建和销毁对象,或者需要在程序的不同阶段创建不同的实例,就不适合使用单例模式。

  3. 需要并发创建多个实例的情景:在多线程环境下,如果多个线程需要并发地创建多个实例,就不适合使用单例模式,因为单例模式只能创建一个实例。

  4. 对象依赖外部状态的情景:如果单例对象依赖外部状态,而且在不同的情况下需要使用不同的外部状态,就不适合使用单例模式。因为单例模式只能创建一个实例,无法根据外部状态的变化来动态地改变对象的行为。

6.1.5、哪些情形适合使用单例模式?

答:

  1. 需要确保系统中只有一个实例存在的情形:某些资源只能被一个实例使用,例如数据库连接池、线程池等。
示例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolSingleton {

    private static ExecutorService instance;

    private ThreadPoolSingleton() {
        // 私有构造函数,防止外部创建实例
    }

    public static ExecutorService getInstance() {
        if (instance == null) {
            synchronized (ThreadPoolSingleton.class) {
                if (instance == null) {
                    instance = Executors.newFixedThreadPool(10);
                }
            }
        }
        return instance;
    }
}
上述代码使用双重检查锁定(Double-Checked Locking)来确保线程安全。
在getInstance方法中,首先进行一次检查,如果实例已经被创建了,则直接返回实例。
如果实例还未被创建,则获取锁,并再次检查实例是否已经被创建。
如果实例仍未被创建,则创建一个新的线程池实例,并将其赋值给instance变量。
这样,通过getInstance方法获取到的线程池对象始终是同一个实例,确保了线程池的单例性。
  1. 需要提供一个全局访问点来访问唯一实例的情形:在整个系统中需要共享某个对象的实例,例如日志记录器、配置文件管理器等。

  2. 需要频繁创建和销毁相同对象的情形:由于创建和销毁对象的开销较大,使用单例模式可以减少对象的创建和销毁次数,提高性能。

  3. 需要用于替代全局变量的情形:全局变量容易被滥用,而单例模式可以提供一个更优雅的方式来管理全局状态。

总的来说,适合使用单例模式的情形是在需要确保只有一个实例存在、需要共享某个实例以及减少对象创建和销毁次数的情况下。

标签:Singleton,单例,创建,instance,实例,线程,6.1,设计模式
From: https://blog.csdn.net/weixin_61769871/article/details/142422210

相关文章

  • 重修设计模式-行为型-责任链模式
    重修设计模式-行为型-责任链模式将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。责任链模式(ChainofResponsibilityPattern)也叫职责链模式,通过将请求的处理分配......
  • C++—单例设计模式
    单例设计模式C++中的单例设计模式是一种常用的软件设计模式,其核心目的是确保一个类仅有一个实例,并提供一个全局访问点来获取这个实例。以下是对C++单例设计模式的详细解释:一、单例设计模式的定义单例模式(SingletonPattern)是一种创建型设计模式,它确保一个类只有一个实例,......
  • 常用并发设计模式精讲
    1.优雅终止线程的设计模式思考:在一个线程T1中如何优雅的终止线程T2?正确思路:两阶段终止模式1.1两阶段终止(Two-phaseTermination)模式——优雅的终止线程两阶段终止(Two-phaseTermination)模式是一种用于优雅终止线程的设计模式。该模式的基本思想是通过两个阶段来终止......
  • 一个基于Transformer模型的中文问答系统926.1
    这个代码实现了一个基于Transformer模型的中文问答系统。以下是代码的主要功能和可能的完善方向:主要功能数据处理:代码首先定义了处理中文文本的函数,包括分词、构建词汇表、将句子转换为张量等。数据加载:从.jsonl或.json文件中加载问题和答案数据,并进行数据增强。模型定......
  • Python设计模式速通
    目录先导对象的事情类的事情方法面对对象程序设计的几个基本要点封装多态继承抽象组合面对对象程序设计的准则开放/封闭原则控制反转原则接口隔离原则单一职责原则替换原则规定三大模式创建型模式结构型模式行为型模式先导我们开始设计模式之前,首先第......
  • 技术成神之路:设计模式(十五)中介者模式
    介绍中介者模式(MediatorPattern)是一种行为型设计模式,用于减少对象之间的复杂通信和依赖。它通过引入一个中介者对象来封装对象之间的交互,从而使得对象之间不直接相互依赖,而是通过中介者进行通信。1.定义中介者模式将对象之间的通信封装到一个中介者对象中,使各对象不再直接引用彼......
  • 设计模式之组合模式
    组合模式组合模式是一种结构型设计模式,用于将对象组织成树形结构以表示部分-整体的层次关系。它使得客户端可以统一地处理单个对象和组合对象。核心概念透明性:组合模式通过使组件的接口包含管理子部件的操作(如添加、删除等),提供了透明的操作方式。这意味着客户端无需关心它正......
  • 设计模式——观察者模式
    设计模式——观察者模式1.天气预报应用案例具体需求:气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)。需要设计开放型API,便于其他第三方也能接入气象站获取数据。提供温度、气压和湿度的接口测量数据更新时,要能实时的通知......
  • 【Linux】多线程:线程池的创建、日志类、RAII互斥锁、单例模式:饿汉方式与懒汉方式
    目录一、线程池概念二、线程的封装及线程池类成员变量的介绍 三、单例模式饿汉方式(EagerInitialization)懒汉方式(LazyInitialization)四、RAII类型的互斥锁 五、日志类的实现六、简单的任务类创建七、线程池的创建 一、线程池概念线程池(ThreadPool)是一种基于......
  • 设计模式_1_单例模式
    单例模式什么是单例设计模式单例模式是一种创建型设计模式,它的核心思想是保证一个类只有一个实例,并提供一个全局访问点来访问这个实例。只有一个实例的意思是,在整个应用程序中,只存在该类的一个实例对象,而不是创建多个相同类型的对象。全局访问点的意思是,为了让其他类能够获......