C++多线程下的单例模式

一、懒汉模式:即第一次调用该类实例的时候才产生一个新的该类实例,并在以后仅返回此实例。

需要用锁,来保证其线程安全性:原因:多个线程可能进入判断是否已经存在实例的if语句,从而non thread safety.

使用double-check来保证thread safety.但是如果处理大量数据时,该锁才成为严重的性能瓶颈。

1、静态成员实例的懒汉模式:

class Singleton
{
private:
    static Singleton* m_instance;
    Singleton(){}
public:
    static Singleton* getInstance();
};

Singleton* Singleton::getInstance()
{
    if(NULL == m_instance)
    {
        Lock();//借用其它类来实现,如boost
        if(NULL == m_instance)
        {
            m_instance = new Singleton;
        }
        UnLock();
    }
    return m_instance;
}

2、内部静态实例的懒汉模式

这里需要注意的是,C++0X以后,要求编译器保证内部静态变量的线程安全性,可以不加锁。但C++ 0X以前,仍需要加锁。

class SingletonInside
{
private:
    SingletonInside(){}
public:
    static SingletonInside* getInstance()
    {
        Lock(); // not needed after C++0x
        static SingletonInside instance;
        UnLock(); // not needed after C++0x
        return instance;
    }
};

二、饿汉模式:即无论是否调用该类的实例,在程序开始时就会产生一个该类的实例,并在以后仅返回此实例。

由静态初始化实例保证其线程安全性,WHY?因为静态实例初始化在程序开始时进入主函数之前就由主线程以单线程方式完成了初始化,不必担心多线程问题。

故在性能需求较高时,应使用这种模式,避免频繁的锁争夺。

class SingletonStatic
{
private:
static const SingletonStatic* m_instance;
SingletonStatic(){}
public:
static const SingletonStatic* getInstance()
{
return m_instance;
}
};

//外部初始化 before invoke main
const SingletonStatic* SingletonStatic::m_instance = new SingletonStatic;

时间: 2024-08-05 09:56:50

C++多线程下的单例模式的相关文章

多线程下的单例模式

参加一个面试,被问到多线程下的单例模式会创建几个对象,总结一下: 首先我的单例是这么写的(懒汉式) public class Singleton{ private static Singleton singleton; private Singleton(){} public Singleton getInstance(){ if(singleton == null){ singleton = new singleton(); } return singleton; } } 这样写的话, 当线程

java工程优化——多线程下的单例模式

在最初学习设计模式时,我为绝佳的设计思想激动不已,在以后的工程中,多次融合设计模式,而在当下的设计中,我们已经觉察出了当初设计模式的高瞻远瞩,但是也有一些不足,需要我们去改进,有人说过,世界上没有绝对的事,当然,再简单的事情,环境变了,也会发生变化,今天和大家一起分享在多线程下单例模式的优化. 1,传统 首先,我们回顾下传统的单例(懒汉式)是如何工作的: public class SingletonClass{ private static SingletonClass instance=nul

4创建型模式之单例模式__多线程下的懒汉式单例和饿汉式单例

//1"懒汉"模式虽然有优点,但是每次调用GetInstance()静态方法时,必须判断 //      NULL == m_instance,使程序相对开销增大. //2多线程中会导致多个实例的产生,从而导致运行代码不正确以及内存的泄露. //3提供释放资源的函数 讨论:   这是因为C++中构造函数并不是线程安全的. C++中的构造函数简单来说分两步: 第一步:内存分配 第二步:初始化成员变量 由于多线程的关系,可能当我们在分配内存好了以后,还没来得急初始化成员变量,就进行线程切换

对于多线程下Servlet以及Session的一些理解

今天,小伙伴突然问到了Servlet是不是线程安全的问题.脑子当时一卡壳,只想到了单实例多线程.这里做一些总结. Servlet体系是建立在Java多线程的基础之上的,它的生命周期是由Tomcat来维护的.当客户端第一次请求Servlet的时候,tomcat会根据web.xml配置文件实例化servlet,当又有一个客户端访问该servlet的时候,不会再实例化该servlet,也就是多个线程在使用这个实例. Servlet线程池 serlvet采用多线程来处理多个请求同时访问,Tomcat容器

Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask

CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就是CyclicBarrier.CyclicBarrier从字面理解是指循环屏障,它可以协同多个线程,让多个线程在这个屏障前等待,直到所有线程都达到了这个屏障时,再一起继续执行后面的动作.看一下CyclicBarrier的使用实例: public static class CyclicBarrierThread extends Thread { private CyclicBarrier cb; private int sleep

Window下高性能IOCP模型队列多线程下应用

IOCP,先从概念上认识一下.IOCP全称I/O Completion Port,中文译为I/O完成端口.是Windows平台最高效的I/O模块,现在IIS服务器,就采用IOCP模型.IOCP是一个异步I/O的API,它可以高效地将I/O事件通知给应用程序.与使用select()或是其它异步方法不同的是,现在很多书,文字都直接将IOCP模块和网络编程关联起来,好像IOCP就是和网络打交道的.典型的IOCP模型的使用,是 将一个套接字(socket)与一个完成端口关联了起来,当一个网络事件发生的时

hashmap,hashtable,concurrenthashmap多线程下的比较(持续更新)

1.hashMap 多线程下put会造成死循环,主要是扩容时transfer方法会造成死循环. http://blog.csdn.net/zhuqiuhui/article/details/51849692(具体原因) 2.hashTable,使用synchornized保证线程安全,线程竞争竞争激烈的情况下,效率低下.当一下线程访问hashTable方法的时候,其他的线程会进入轮询或者阻塞的情况. 如果线程1是用put方法添加元素,线程2不能put元素也不能get元素,所以竞争越激烈越低. 3

HashMap简单源码及多线程下的死循环

主要记录hashMap的一些基本操作源码实现原理以及多线程情况下get()操作的死循环引发原因 一.hashMap简介 1.hashMap集合的主要属性及方法 (默认初始化容量)DEFAULT_INITIAL_CAPACITY = 16 (默认最大容量)MAXIMUM_CAPACITY = 1 << 30 (默认加载因子)DEFAULT_LOAD_FACTOR = 0.75f (Entry数组)Entry[] table (Entry实例的数量)size put(K key, V value)

HashMap为什么在多线程下会让cpu100%

首先HashMap并不是sun公司多线程提供的集合,很多时候我们的程序是一个主线程,用了hashmap并没有什么问题,但是在多线程下会出现问题. hashmap是一个哈希表,存储的数据结构也可以是一个线性数组,我们的存储的数据都在entry里,默认的大小是16, 因子是0.75  当达到16*0.75的时候就会扩充 把原来的数据transfer在新的扩充的容器里,在转换的时候如果是一个线程并没有什么问题,但是在多线程的时候,如果在临界点的时候,如果存储的值得hash值对数组的长度去摸一样,就会存