设计模式 之美 -- 单例模式

为什么要使用单例?

一个类只允许创建一个对象或者实例。

背景简介:使用多线程并发访问同一个类,为了保证类的线程安全,可以有两种方法:

  1. 将该类定义为单例模式,即该类仅允许创建一个实例
  2. 为该类的成员函数添加类级别的锁

举例:

一个向指定文件写入日志的类,为了保证该类并发调用时写入文件的日志不会覆盖,需执行以上操作。

单例模式的几种经典的实现方式:

  • 饿汉式

    在类的加载期间,将静态实例初始化好,所以实例的创建是线程安全的。但是这样的方式不支持延迟加载,且每加载一个实例都会重新初始化一次,开销较大。

  • 懒汉式

    懒汉模式相对于饿汉模式的优点是支持延迟加载(C++ 种的动态绑定),只有实例化的时候才知道该对象的实例。但是会导致出现频发加锁,释放锁造成效率底下 的问题。

  • 双重检测

    双重检测既支持延迟加载,又支持高并发的单例实现方式。

  • 静态内部类

    JAVA支持的静态内部类实现单例。这种实现方式既支持延迟加载,也支持高并发实例,实现起来也比双重检测简单。

  • 枚举

    最简单的实现方式,基于枚举实现的单例。通过枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性。

C语言单例模式的实现:

饿汉模式

csingleton.h

#ifndef CSINGLETON_H
#define CSINGLETON_H
#include 

typedef struct {
    void* (*ctor)(void *_self);
    void* (*dtor)(void *_self);
    void* (*createInstance)(void *self);
    void *instance;
} _CSingleton;

extern const void *CSingleton;
void *GetInstance(void);

#endif

csingleton.c

#include "csingleton.h"
#include 


static void *csingletonCtor(void *_self) {
    _CSingleton *self = _self;

    self->instance = _self;
    return self;
}

static void *csingletonDtor(void *_self) {
    _CSingleton *self = _self;

    self->instance = NULL;
    return self;
}

static void *csingletonCreateInstance(void *_self) {
    _CSingleton *self = _self;

    self->instance = _self;
    return self;
}

static _CSingleton _csingleton = {
    csingletonCtor, csingletonDtor, csingletonCreateInstance, NULL
};
const void *CSingleton = &_csingleton;

void *GetInstance(void) { //当调用该函数加载类的时候进行初始化
    if (NULL == ((_CSingleton*)CSingleton)->instance) {
        return csingletonCtor(CSingleton);
    } else {
        return ((_CSingleton*)CSingleton)->instance;
    }
}

main.c

#include "csingleton.h"
#include 

int main(int argc, char *argv[]) {
    
	void *ps1 = GetInstance();
    void *ps2 = GetInstance();
    if (ps1 == ps2) {
    	fprintf(stdout, "ps1 = ps2\n");
    }
    
    return 0;
}

懒汉模式

#include 
#include 
#include 
#include 
#include 

typedef struct ID{
	char *name;
	int id_num;
}id;


static id *_id = NULL;

/*通过锁进行并发访问时线程间竞争的控制*/
static omp_lock_t lock;

id *getInstance(){
	omp_set_lock(&lock);
	
	if(NULL != _id) {
		omp_unset_lock(&lock);
		return _id;
	} else {
		_id = (id*)malloc(sizeof(id));
		assert(_id != NULL);
		omp_unset_lock(&lock);
		return _id;
	}
}


int main(int argc, char *argv[]) {
	
	omp_set_num_threads(20);//运行时的库函数,设置运行的线程数目
	id * i1, *i2;
	
	omp_init_lock(&lock);
	{
        i1 = getInstance() ;
        i1->name = "Rong";
        i1->id_num = omp_get_thread_num();
	}
	 	
    {
        i2 = getInstance() ;
        i2->name = "Tao";
    }
	omp_destroy_lock(&lock);
	
	if(i1 == i2){
		fprintf(stdout, " i1 == i2 \n");
	}
	fprintf(stdout, "i1->name = %s, i1->score = %d\n",i1->name, i1->id_num);
	fprintf(stdout, "i2->name = %s, i2->score = %d\n",i2->name, i2->id_num);
	return 0;
}

C++实现单例模式

饿汉模式

#include 
using namespace std;

class Singleon
{
private:

	Singleon()
	{
		cout << "Singleon()" << endl;
	}

	static Singleon* instance;
public:
	static Singleon* GetSingleon()
	{
		return instance;
	}
    
	static Singleon* Destroy()
	{
		delete instance;
		instance = NULL;
	}
};

/*编译加载类的时候即初始化,静态成员编译的时候即会初始化*/
Singleon* Singleon::instance = new Singleon();

int main()

{
	Singleon* sl1 = Singleon::GetSingleon();
	Singleon* sl2 = Singleon::GetSingleon();
	Singleon* sl3 = Singleon::GetSingleon();
	cout << sl1 << endl;
	cout << sl2 << endl;
	cout << sl2 << endl;
	system("pause");
	return 0;

}

懒汉模式

#include 
using namespace std;

class Singleon
{
private:
	Singleon()
	{
		cout << "Singleon()" << endl;
	}
	static Singleon*instrance;
public:
	static Singleon* GetSingleon()
	{
		if (NULL == instrance)
		{
			instrance = new Singleon();
			cout << "对象创建成功" << endl;
		}
		else
		{
			cout << "对象已经创建成功,无须再建" << endl;
		}
		return instrance;
	}
	static Singleon* Destroy()
	{
		delete instrance;
		instrance = NULL;
	}
};

/*类加载的时候不进行初始化,实例化的时候进行初始化*/
Singleon* Singleon::instrance =  NULL;
int main()
{
	Singleon* sl1 = Singleon::GetSingleon();
	Singleon* sl2 = Singleon::GetSingleon();
	Singleon* sl3 = Singleon::GetSingleon();
	cout << sl1 << endl;
	cout << sl2 << endl;
	cout << sl2 << endl;
	system("pause");
	return 0;
}

你可能感兴趣的:(设计模式,#,编程语言:C++,#,编程语言C)