线程安全的单实例模式

我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作由一个public的类方法代劳,该方法也返回单例类唯一的实例。单例大约有两种实现方法:懒汉与饿汉。
懒汉:故名思义,不到万不得已就不会去实例化类,也就是说在第一次用到类实例的时候才会去实例化,节省内存。
饿汉:饿了肯定要饥不择食。所以在单例类定义的时候就进行实例化。浪费内存
特点与选择:
由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。
在访问量较小时,采用懒汉实现。这是以时间换空间。

首先是饿汉模式:

饿汉,线程安全,不会内存泄漏
class singleton
{
private:
static singleton*p;
singleton() {}
~CSingleton()
  {
   if (p== NULL) { return ;}
   delete P;
   P = NULL;
   }
public:
    static singleton* initance();
    singleton* p = new singleton();//饿汉的体现,直接实例化,也就不存在线程不安全了。
    singleton* initance()
    {
      return p;
    }
};

  懒汉模式:

方法一:使用加锁来达到线程安全

class singleton
{
protected:
  singleton()
  {
    pthread_mutex_init(&mutex);
  }
private:
  static singleton* p;
public:
  static pthread_mutex_t mutex;
  static singleton* initance();
};

pthread_mutex_t singleton::mutex;
singleton* singleton::p = NULL;
singleton* singleton::initance()
{
  if (p == NULL)
  {
    pthread_mutex_lock(&mutex);
    if (p == NULL)
      p = new singleton();
    pthread_mutex_unlock(&mutex);
  }
  return p;
}

  方法二:使用内部静态变量来达到线程安全

class singleton
{
protected:
  singleton()
  {
    pthread_mutex_init(&mutex);
  }
public:
  static pthread_mutex_t mutex;
  static singleton* initance();
  int a;
};

pthread_mutex_t singleton::mutex;
singleton* singleton::initance()
{
  pthread_mutex_lock(&mutex);
  static singleton obj;
  pthread_mutex_unlock(&mutex);
  return &obj;
}

  

原文地址:https://www.cnblogs.com/wuyepeng/p/9601936.html

时间: 2024-11-08 02:57:29

线程安全的单实例模式的相关文章

设计模式(三)单实例模式

引言 对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务:一个系统只能有一个窗口管理器或文件系统:一个系统只能有一个计时工具或ID(序号)生成器.如在Windows中就只能打开一个任务管理器.如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源:如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态.因此有时确保

关于python的单实例模式

单实例模式一直是常用的设计模式,对于python的单实例模式,其实其本身就有实现 http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/31887#31887 里面说到module,module只会初始化一次,天然的singleton.这是最为python的解决方案.将你所需要的属性和方法,直接暴露在模块中变成模块的全局变量和方法即可. 另外,如果

python的单实例模式

先看下单实例的定义 这里我们主要学习一下基于模块实现单例对象,这里利用的原理就是python的模块导入的特性,这个模块被第一次导入,会被执行一次,但是如果这个模块被再次导入,无论是在相同的文件还是在不同的文件中,第二次导入都不会再次执行 如果要想通过模块导入实现单实例模式,则必须要在一个文件中定义一个类,这里要切记,在这个文件中一定要实例化这个类,然后在其他文件中导入这个实例对象,那么所有的文件中用的实例对象都是相同的一个 比如我们看下下面的例子 在mysingle.py文件中我们定义了一个类,

单实例模式和互斥访问

场景说明:在实际的应用开发中,很多人没有注意到一点:在生成单实例的过程中,如果由线程去创建对象的实例,有可能在第一次检测到对象不存在的情况下,准备创建对象,此时由于多线程的缘故,恰巧当前线程被挂起,另一个线程同样执行到这个语句,于是创建一个对象,另一个线程冲睡眠中被唤醒,于是执行了创建对象,现在就有两个对象,完全背离了单实例的设计模式, 解决方法: 1)在主线程还没有创建多线程的时候,创建单实例,但是这里有一个问题:就不会达到延时加载的效果,变成了急剧加载,也就是说预先加载了对象,可能这个对象根

单实例模式

  前言:   单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中(jvm)一个类只有一个实例.即一个类只有一个对象实例:这几种模式有几种好处: 1.可以避免实例存在多个引起程序的逻辑错误(比如一个国家有多个主席,肯定会一团糟) 2.某些创建频繁的类,使用单列模式可以减轻内存的压力 3.因为类控制了实例化过程,所以类可以灵活更改实例化过程.   单列模式的三种模式: 1.饿汉模式 //饿汉式--典型的穷屌丝,吃了上顿没下顿.所以要提前准备(

3.1.17 自定义元类控制类的实例化的应用--单实例模式

#单例模式#实现方式一:# class MySQL:# __instance=None #__instance=obj1## def __init__(self):# self.host='127.0.0.1'# self.port=3306## @classmethod# def singleton(cls):# if not cls.__instance:# obj=cls()# cls.__instance=obj# return cls.__instance### def conn(se

C#设计模式-单实例

单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点. 1.经典的模式 namespace singleClass { class OnlyOneClass { private OnlyOneClass() { } private static OnlyOneClass instance; public static OnlyOneClass getInstance() { if (instance == null) { in

MySQL MGR集群单主模式的自动搭建和自动化故障修复

/*the waiting game:尽管人生如此艰难,不要放弃:不要妥协:不要失去希望*/ 随着MySQL MGR的版本的升级以及技术成熟,在把MHA拉下神坛之后, MGR越来越成为MySQL高可用的首选方案.MGR的搭建并不算很复杂,但是有一系列手工操作步骤,为了简便MGR的搭建和故障诊断,这里完成了一个自动化的脚本,来实现MGR的自动化搭建,自动化故障诊断以及修复. MGR自动化搭建为了简便起见,这里以单机多实例的模式进行测试,先装好三个MySQL实例,端口号分别是7001,7002,70

servlet单实例多线程模式

前言:Servlet/JSP技术和ASP.PHP等相比,由于其多线程运行而具有很高的执行效率.由于Servlet/JSP默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的安全性问题. JSP的中存在的多线程问题: 当客户端第一次请求某一个JSP文件时,服务端把该JSP编译成一个CLASS文件,并创建一个该类的实例,然后创建一个线程处理CLIENT端的请求.如果有多个客户端同时请求该JSP文件,则服务端会创建多个线程.每个客户端请求对应一个线程.以多线程方式执行可大大降低对系统