设计模式:单例模式(singleton)
singleton模式属于创建型设计模式。其作用是在程序设计中,对于某一个类而言,全局只能存在一个实例对象。
下面以C++为例,对单例模式进行说明:
1. 最基本单例模式(单线程)
 class Singleton1{
     private:
         static Singleton1 instance;
         Singleton1(){}            //构造函数
     public:
         static Singleton1 get_instance(){
             if (Singleton1.instance==nullptr){   //若当前唯一实例为空,则创建新对象返回
                 instance=Singleton1();
             }
             return instance;
         }
 };
存在问题:在单线程下,只有instance == null 时,才会创建新对象,其余时间返回。但是对于多线程访问时,当两个或多个线程同时访问到instance==null,若判断成立,多个线程会分别实例化对象,这时程序就不满足单例条件了。
2.多线程的单例模式
针对上述问题,要在多线程中保证单例,就要进行线程同步控制,C++中使用mutex类族进行同步控制。
class Singleton2{
    private:
        static Singleton2 instance;
        static std::mutex mutex_var;
        Singleton2(){}
    public:
        static Singleton2 get_instance(){
            mutex_var.lock();           //互斥量加锁进行线程同步
            if (instance==nullptr){
                instance=Singleton2();
            }
            mutex_var.unlock();         //互斥量解锁
            return instance;
        }
};
存在问题:线程安全,但程序效率不高。注意,此前讨论的出现的不满足单例的情况只出现在首次实例化对象时,但现在的程序在每次通过ger_instance函数访问时,都会进行加解锁操作,,加锁操作是十分耗时的,从而导致程序效率变低。
3.多线程下高效的单例模式
解决方法:仅在第一次实例化的时候加锁,其他时刻不加锁,提高程序效率。
class Singleton3{
    private:
        static Singleton3 instance;
        static std::mutex mutex_var;
        Singleton3(){}
    public:
        static Singleton3 get_instance(){
            if (instance==nullptr)         //外层多一次判断,如果单例已经存在,就不再进行加锁操作
            {
                mutex_var.lock();           //互斥量加锁进行线程同步
                if (instance==nullptr){
                    instance=Singleton3();
                }
                mutex_var.unlock();         //互斥量解锁
            }
            return instance;
        }
};
关于懒汉式和饿汉式的讨论
饿汉式:单例实例在类装载时就构建,急切初始化。(预先加载法)
懒汉式:单例实例在第一次被使用时构建,延迟初始化。(上述实现都是懒汉式的)。
这两类单例模式的区别在于实例化的时机不同。
饿汉式
优点:线程安全,在类加载的同时创建一个静态对象,调用时反应快。缺点:由于是提前定义,可能在全局程序中都没有使用这个实例,资源利用率不高。
懒汉式
优点:资源效率高,只要不用到该实例就不会被实例化。缺点:第一次加载速度不快。
两种方式各有优劣,针对不同的场景进行选择,一般情况下,使用饿汉式更多一些。
设计模式:单例模式(singleton)的更多相关文章
- 设计模式 单例模式(Singleton) [ 转载2 ]
		
设计模式 单例模式(Singleton) [ 转载2 ] @author java_my_life 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类 ...
 - 设计模式 单例模式(Singleton) [ 转载 ]
		
设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创 ...
 - JAVA设计模式-单例模式(Singleton)线程安全与效率
		
一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...
 - 浅谈设计模式--单例模式(Singleton Pattern)
		
题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...
 - [工作中的设计模式]单例模式singleton
		
一.模式解析: 单例模式是最简单和最常用的设计模式,面试的时候,不管新毕业的学生还是已经工作多年的筒子,对单例模式基本都能聊上两句.单例模式主要体现在如下方面: 1.类的构造函数私有化,保证外部不能直 ...
 - 23种设计模式--单例模式-Singleton
		
一.单例模式的介绍 单例模式简单说就是掌握系统的至高点,在程序中只实例化一次,这样就是单例模式,在系统比如说你是该系统的登录的第多少人,还有数据库的连接池等地方会使用,单例模式是最简单,最常用的模式之 ...
 - 设计模式--单例模式Singleton(创建型)
		
单例模式很显然是定义一个类,这个类在程序中只有唯一的实例对象.一般单例类的构造函数是私有的,只能通过调用静态函数GetInstance来获取实例. 一.单例模式有三种:懒汉式单例.饿汉式单例.登记式单 ...
 - 设计模式--单例模式Singleton
		
单例模式顾名思义整个程序下只有一个实例,例如一个国家只有一个皇帝,一个军队只有一个将军.单例模式的书写又分为饿汉模式和懒汉模式 饿汉模式 类中代码 package demo; public cla ...
 - 设计模式——单例模式(Singleton)
		
保证一个类仅有一个实例,并提供一个访问它的全局访问点.——DP UML类图 模式说明 个人认为单例模式是所有设计模式中最为简单的一个模式,因为实现这个模式仅需一个类,而不像其他模式需要若干个类.这个模 ...
 - 设计模式-单例模式(Singleton) (创建型模式)
		
//以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Singleton.h #pragma once #include<iostream> class Sin ...
 
随机推荐
- 免密码登录postgresql
			
如果在当前shell 下,如果设定 export PGPASSWORD='postgres密码' 环境变量,可以不用每次执行sql 语句或者导入一个sql 文件都输入一次密码的麻烦了.
 - appium---adb logcat 命令详解
			
我们在做app测试的过程中,肯定会遇到需要抓取日志问题,这几天安静也遇到了此问题,后台日志生成的太多了,保存本地了吧,设备多没有这么USB,通过wifi连接又太麻烦,你说这怎么是好?不要着急,我们往下 ...
 - fake_useragent.json
			
{ "browsers": { "chrome": [ "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.3 ...
 - Java JDK 运行环境安装
			
1 Windows系统 1.1 安装包准备 安装包本文档讲解为64位系统,如果是32位系统需要下载32位系统安装包 1.1.1 下载方式 打开jdk官方下载地址,该文档提供jdk版本为1.8 http ...
 - 类数组(Array-like)对象应用
			
类数组(Array-like)对象 slice 方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组.你只需将该方法绑定到这个对象上. 一个函数中的 arguments 就是一 ...
 - 《LSM算法原理》
			
记内存中的树为T0, 硬盘上的树按时间顺序,记做T1, ..., Tk 读: T0 Tk -> Tk-1 -> ... -> T0 写 T0 T0超过一定大小后,插入硬盘变为Tk+1 ...
 - Python中文注释报错的解决方法
			
在Python的程序中加了中文注释会报错 解决方法是:在程序的最开始位置加入 # -- coding: utf-8 --
 - Nginx企业级优化
			
Nginx企业级优化 一.隐藏版本号信息 安装软件前修改,源码包中的版本信息 #切换到源码包目录[root@localhost ~]# cd /usr/src/nginx-1.15.9/[root@l ...
 - Paper | Multi-scale Dense Networks for Resource Efficient Image Classification
			
目录 故事背景 方法 两种加速策略 网络设计 网络优化 失败设计 回头品味 实验 数据集和数据处理 结果 第二次阅读 本文不是第一个提出early exit思想的 写作流畅 网络回顾 其他 发表在IC ...
 - 改善java程序的151个建议
			
<编写高质量代码-改善java程序的151个建议> --秦小波 第一章.开发中通用的方法和准则 1.不要在常量和变量中出现易混淆的字母 long a=0l; --> long a=0 ...