广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java单例模式分析
  • 411
分享到

Java单例模式分析

2024-04-02 19:04:59 411人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录单例模式为什么要用单例单例的关键点几种写法懒汉式饿汉式静态内部类写法枚举单例容器实现单例参考总结单例模式 为什么要用单例 确保某个类只有一个对象,常用于访问数据库操作,服务的配置

单例模式

为什么要用单例

确保某个类只有一个对象,常用于访问数据库操作,服务的配置文件等。

单例的关键点

1、默认构造函数为private,复制构造函数和复制赋值函数也要private或=delete禁用。(做到无法被外部其他对象构造)

2、通过一个静态方法或枚举返回单例类对象。

3、确保多线程的环境下,单例类对象只有一个。

几种写法

本文主要介绍c++的懒汉式和饿汉式写法。

懒汉式

需要生成唯一对象时(调用GetInstance时),才生成

线程不安全的错误写法


class SingleInstance
{
public:
    // 静态方法获取单例
    static SingleInstance *GetInstance();
    // 释放单例避免内存泄露
    static void deleteInstance();
private:
    SingleInstance() {}
    ~SingleInstance() {}
    // 复制构造函数和复制赋值函数设置为private,被禁用
    SingleInstance(const SingleInstance &signal);
    const SingleInstance &operator=(const SingleInstance &signal);
private:
    static SingleInstance *m_SingleInstance;
};

// 初始化为NULL,与后面形成对比
SingleInstance *SingleInstance::m_SingleInstance = NULL;

SingleInstance* SingleInstance::GetInstance()
{
    // 多线程情况下,一个线程通过if检查但是还未new出单例时,另一个线程也通过了if检查,导致new出多个对象
    if (m_SingleInstance == NULL)
    {
        m_SingleInstance = new (std::nothrow) SingleInstance;
    }
    return m_SingleInstance;
}

void SingleInstance::deleteInstance()
{
    if (m_SingleInstance)
    {
        delete m_SingleInstance;
        m_SingleInstance = NULL;
    }
}

线程安全的双检锁写法


class SingleInstance
{
public:
    // 静态方法获取单例
    static SingleInstance *GetInstance();
    // 释放单例避免内存泄露
    static void deleteInstance();
private:
    SingleInstance() {}
    ~SingleInstance() {}
    // 复制构造函数和复制赋值函数设置为private,被禁用
    SingleInstance(const SingleInstance &signal);
    const SingleInstance &operator=(const SingleInstance &signal);
private:
    static SingleInstance *m_SingleInstance;
};

// 初始化为NULL,与后面形成对比
SingleInstance *SingleInstance::m_SingleInstance = NULL;

SingleInstance* SingleInstance::GetInstance()
{
    // 如果直接在外面,功能也ok,但每次运行到这个地方便需要加一次锁,非常浪费资源
    // 在里面加锁,初始化时存在加锁的情况,初始化之后,外层if都为false,直接返回,避免加锁
    if (m_SingleInstance == NULL) 
    {
        std::unique_lock<std::mutex> lock(m_Mutex); // Lock up
        if (m_SingleInstance == NULL)
        {
            m_SingleInstance = new (std::nothrow) SingleInstance;
        }
    }
    return m_SingleInstance;
}

void SingleInstance::deleteInstance()
{
    if (m_SingleInstance)
    {
        delete m_SingleInstance;
        m_SingleInstance = NULL;
    }
}

线程安全的局部静态变量写法

推荐


class SingleInstance
{
public:
    // 静态方法获取单例
    static SingleInstance *GetInstance();
private:
    SingleInstance() {}
    ~SingleInstance() {}
    // 复制构造函数和复制赋值函数设置为private,被禁用
    SingleInstance(const SingleInstance &signal);
    const SingleInstance &operator=(const SingleInstance &signal);
};

SingleInstance& SingleInstance::GetInstance()
{
	// 局部静态变量(一般为函数内的静态变量)在第一次使用时分配内存并初始化。
    static SingleInstance m_SingleInstance;
    return m_SingleInstance;
}

饿汉式

进程运行前(main函数执行),就创建

线程安全的进程运行前初始化写法


class SingleInstance
{
public:
    // 静态方法获取单例
    static SingleInstance *GetInstance();
private:
    SingleInstance() {}
    ~SingleInstance() {}
    // 复制构造函数和复制赋值函数设置为private,被禁用
    SingleInstance(const SingleInstance &signal);
    const SingleInstance &operator=(const SingleInstance &signal);
private:
	static SingleInstance *m_SingleInstance;
};

SingleInstance* SingleInstance::GetInstance()
{
    return m_SingleInstance;
}

// 全局变量、文件域的静态变量和类的静态成员变量在main执行之前的静态初始化过程中分配内存并初始化
Singleton* Singleton::g_pSingleton = new (std::nothrow) Singleton;
int main()
{
	return 0;
}

线程安全的类静态成员变量写法


class SingleInstance
{
public:
    // 静态方法获取单例
    static SingleInstance *GetInstance();
    // 全局变量、文件域的静态变量和类的静态成员变量在main执行之前的静态初始化过程中分配内存并初始化。
    static SingleInstance m_SingleInstance;
private:
    SingleInstance() {}
    ~SingleInstance() {}
    // 复制构造函数和复制赋值函数设置为private,被禁用
    SingleInstance(const SingleInstance &signal);
    const SingleInstance &operator=(const SingleInstance &signal);
};

SingleInstance& SingleInstance::GetInstance()
{
    return m_SingleInstance;
}

静态内部类写法

JAVA



public class Singleton {
    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }

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

第一次加载Singleton类时不会初始化instance,只有在第一次调用getInstance()方法时,虚拟机会加载SingletonHolder类,初始化instance。
这种方式既保证线程安全,单例对象的唯一,也延迟了单例的初始化,推荐使用这种方式来实现单例模式。

枚举单例

JAVA



public enum SingletonEnum {
    INSTANCE;
    public void doSomething() {
        System.out.println("do something");
    }
}

默认枚举实例的创建是线程安全的,即使反序列化也不会生成新的实例,任何情况下都是一个单例。
优点: 简单!

容器实现单例

JAVA


import java.util.HashMap;
import java.util.Map;

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

    public static void regsiterService(String key, Object instance) {
        if (!objMap.containsKey(key)) {
            objMap.put(key, instance);
        }
    }

    public static Object getService(String key) {
        return objMap.get(key);
    }
}

SingletonManager可以管理多个单例类型,使用时根据key获取对象对应类型的对象。这种方式可以通过统一的接口获取操作,隐藏了具体实现,降低了耦合度。

参考

单例模式的6种实现方式

软件开发常用设计模式—单例模式总结(c++版)

https://stackoverflow.com/questions/1008019/c-singleton-design-pattern

Https://programmer.ink/think/summary-of-c-thread-safety-singleton-patterns.html

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: Java单例模式分析

本文链接: https://www.lsjlt.com/news/137124.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java单例模式分析
    目录单例模式为什么要用单例单例的关键点几种写法懒汉式饿汉式静态内部类写法枚举单例容器实现单例参考总结单例模式 为什么要用单例 确保某个类只有一个对象,常用于访问数据库操作,服务的配置...
    99+
    2022-11-12
  • java单例模式的示例分析
    这篇文章主要介绍了java单例模式的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。定义:      &nb...
    99+
    2023-05-30
    java
  • 用实例分析Java单例模式
    这篇文章主要用实例分析Java单例模式,内容简而易懂,希望大家可以学习一下,学习完之后肯定会有收获的,下面让小编带大家一起来看看吧。本文实例讲述了Java单例模式。分享给大家供大家参考,具体如下:在实际开发的时候会有一些需求,在某个类中只能...
    99+
    2023-05-31
    java 单例模式 ava
  • JAVA的单例模式实例分析
    这篇文章主要介绍“JAVA的单例模式实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JAVA的单例模式实例分析”文章能帮助大家解决问题。一、单例模式是什么?单例(Singleton)模式的定义...
    99+
    2023-06-29
  • 分析Java中的单例模式
    本篇内容主要讲解“分析Java中的单例模式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“分析Java中的单例模式”吧!WHAT维基百科给出了解释、实现的思路以及应该注意的地方:单例模式,也叫单子...
    99+
    2023-06-25
  • Java设计模式的单例模式实例分析
    本文小编为大家详细介绍“Java设计模式的单例模式实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java设计模式的单例模式实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是单例模式单例模式(S...
    99+
    2023-06-29
  • Java中的单例模式实例分析
    本篇内容介绍了“Java中的单例模式实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、定义单例模式(Singleton Patter...
    99+
    2023-06-29
  • C++单例模式实例分析
    本篇内容介绍了“C++单例模式实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!不能被拷贝的类拷贝只会放生在两个场景中:拷贝构造函数以及...
    99+
    2023-06-29
  • Java 实例解析单例模式
    目录单例模式的介绍优点缺点SynchronizedSynchronized示例Synchronized与非SynchronizedSingleton第一个示例第二个示例第三个示例第四...
    99+
    2022-11-12
  • C#单例模式的示例分析
    这篇文章给大家分享的是有关C#单例模式的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。单例模式也是创建型模式的一种,也是23种设计模式中比较简单的一种。见名思意,在整个软件系统中,只有某个类型的一个对象,...
    99+
    2023-06-29
  • java设计模式之单例模式解析
    单例模式是最简单但同时也是很重要的一种设计模式,优点有以下几个方面:当内存占用特别大的类需要频繁地创建销毁时,单例模式可以节省内存和提高性能,例如myBatis里面的sessionFactory当需要对文件做单一读写时,例如同一时间只能同时...
    99+
    2023-05-31
    java 设计模式 单例模式
  • Java中单例模式与多线程的示例分析
    这篇文章主要介绍了Java中单例模式与多线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。单例模式与多线程单例模式就是全局唯一但是所有程序都可以使用的对象写单例模式...
    99+
    2023-06-20
  • Java设计者模式简单工厂模式的示例分析
    这篇文章主要介绍Java设计者模式简单工厂模式的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!简介简单工厂模式 (Simple Factory) 又叫静态工厂方法(Static Factory Method)...
    99+
    2023-05-30
    java
  • PHP中单例模式的示例分析
    这篇文章将为大家详细讲解有关PHP中单例模式的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、什么是单例模式?含义     作为对象的创建模式,单例模式确保某一个类...
    99+
    2023-06-20
  • java模板模式的示例分析
    这篇文章主要介绍java模板模式的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Java设计模式-模板模式什么是模板模式?模板模式,顾名思义,就是通过模板拓印的方式。定义模板,就是定义框架、结构、原型。定义一...
    99+
    2023-06-20
  • JAVA 枚举单例模式及源码分析的实例详解
    JAVA 枚举单例模式及源码分析的实例详解      单例模式的实现有很多种,网上也分析了如今实现单利模式最好用枚举,好处不外乎三点:线程安全不会因为序列化而产生新实例防止反射攻击但是貌似没...
    99+
    2023-05-31
    java 枚举 单例
  • Java享元模式示例分析
    这篇文章主要介绍了Java享元模式示例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java享元模式示例分析文章都会有所收获,下面我们一起来看看吧。定义享元模式(FlyWeight Pattern),也叫蝇...
    99+
    2023-06-29
  • Java策略模式实例分析
    这篇文章主要讲解了“Java策略模式实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java策略模式实例分析”吧!优点算法可以自由切换。避免使用多重条件判断。扩展性良好。缺点策略类会增...
    99+
    2023-06-29
  • Java工厂模式实例分析
    今天小编给大家分享一下Java工厂模式实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。优点一个调用者想创建一个对象,只...
    99+
    2023-06-29
  • Java外观模式示例分析
    本篇内容介绍了“Java外观模式示例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!定义外观模式为多个复杂的子系统,提供了一个一致的界面,...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作