单例模式

/*
	a)构造函数私有化
	b)提供一个全局的静态方法(全局访问点)
	c)在类中定义一个静态指针,指向本类的变量的静态变量指针
	d)拷贝构造函数和赋值函数私有化 
*/
//单例懒汉模式
#include <iostream>
#include <unistd.h>

using namespace std;

class CSingle_lh{
public:
	static CSingle_lh* getInstance()
	{
		//1"懒汉"模式虽然有优点,但是每次调用getInstance()静态方法时,必须判断
		//	NULL == m_instance,使程序相对开销增大。
		//2多线程中会导致多个实例的产生,从而导致运行代码不正确以及内存的泄露。
		//3提供释放资源的函数
		if (NULL == m_pins)
		{
			m_pins = new CSingle_lh;
			m_cnt++;
		}
		return m_pins;
	}
	
	static void printCnt()//测试函数
	{
		cout<<"m_cnt:"<<m_cnt<<"m_pins:"<<m_pins<<endl;
	}
	//释放资源函数
	static CSingle_lh* releaseInstance()
	{
		if (m_pins != NULL)
		{
			delete m_pins;
			m_pins = NULL;
		}
		return m_pins;
	}
private:	
	//构造函数设置为私有防止类外客户创建新对象
	CSingle_lh()
	{
		m_cnt = 0;
		m_pins = NULL;
		sleep(5);//用于测试多线程
	}
	//拷贝构造函数和赋值重载函数设置私有防止类外客户创建新和赋值对象
	CSingle_lh(const CSingle_lh& cs){;}
	CSingle_lh& operator=(const CSingle_lh& cs){;}
	
private:
	static CSingle_lh* m_pins;
	static int m_cnt;	
};

//静态成员变量类中声明,类外初始化
int CSingle_lh::m_cnt = 0;
CSingle_lh* CSingle_lh::m_pins = NULL;

//单线程	
void test1()
{
	CSingle_lh* pins = CSingle_lh::getInstance();
	pins->printCnt();
	pins->releaseInstance();
}


void* func(void* arg)
{
	CSingle_lh* pins = CSingle_lh::getInstance();
	pins->printCnt();
	pins->releaseInstance();
}


//多线程
void test2()
{
	int i = 0;
	pthread_t id[10];
	for(i = 0; i<10; i++)
	{
		pthread_create(&id[i], NULL, func, NULL);
	}
	
	for(i = 0; i<10; i++)
	{
		pthread_join(id[i], NULL);
	}
}


int main()
{
	//test1();
	test2();
	return 0;
}
test2()多线程运行结果,发现对象确实多次创建,线程不安全:
m_cnt:1m_pins:0x7f8e9c0008c0
m_cnt:2m_pins:0x7f8e940008c0
m_cnt:3m_pins:0x7f8e980008c0
m_cnt:4m_pins:0x7f8e8c0008c0
m_cnt:5m_pins:0x7f8e900008c0
m_cnt:6m_pins:0x7f8e840008c0
m_cnt:7m_pins:0x7f8e880008c0
m_cnt:8m_pins:0x7f8e7c0008c0
m_cnt:9m_pins:0x2052730
m_cnt:10m_pins:0x7f8e7c0008e0
/*
C++中的构造函数简单来说分两步:
第一步:内存分配
第二步:初始化成员变量
由于多线程的关系,可能当我们在分配内存好了以后,还没来得急初始化成员变量,
就进行线程切换,另外一个线程拿到所有权后,由于内存已经分配了,
但是变量初始化还没进行,因此打印成员变量的相关值会发生不一致现象
*/
//单例饿汉模式
#include <iostream>
#include <unistd.h>

using namespace std;

class CSingle_eh{

public:
	//直接返回对象的指针
	static CSingle_eh* getInstance()
	{
		return m_pins;
	}
	
	static void printCnt()
	{
		cout<<"m_cnt:"<<m_cnt<<"m_pins:"<<m_pins<<endl;
	}
	//释放对象资源函数
	static CSingle_eh* releaseInstance()
	{
		if (m_pins != NULL)
		{
			delete m_pins;
			m_pins = NULL;
		}
		return NULL;
	}
private:	
	//构造函数设置为私有防止类外客户创建新对象
	CSingle_eh()
	{
		m_cnt++;
		m_pins = NULL;
		sleep(2);
	}
	//拷贝构造函数和赋值重载函数设置私有防止类外客户创建新和赋值对象
	CSingle_eh(const CSingle_eh& cs){;}
	CSingle_eh& operator=(const CSingle_eh& cs){;}

private:
	static CSingle_eh* m_pins;
	static int m_cnt;	
};

//静态成员变量类中声明,类外初始化
int CSingle_eh::m_cnt = 0;
//饿汉式对象指针在类外直接new
CSingle_eh* CSingle_eh::m_pins = new CSingle_eh;

//单线程	
void test1()
{
	CSingle_eh* pins = CSingle_eh::getInstance();
	pins->printCnt();
	pins->releaseInstance();
}


void* func(void* arg)
{
	CSingle_eh* pins = CSingle_eh::getInstance();
	pins->printCnt();
	if (pins != NULL)
	{
		pins->releaseInstance();
	}
	
}


//多线程单例饿汉模式是线程安全的
void test2()
{
	int i = 0;
	pthread_t id[10];
	for(i = 0; i<10; i++)
	{
		pthread_create(&id[i], NULL, func, NULL);
	}
	
	for(i = 0; i<10; i++)
	{
		pthread_join(id[i], NULL);
	}
}


int main()
{
	//test1();
	test2();
	return 0;
}


//单例懒汉多线程安全模式
#include <iostream>
#include <unistd.h>
#include <pthread.h>
using namespace std;

class CLock{
public:
	CLock()
	{
		pthread_mutex_init(&m_mutex, NULL);
	}
	~CLock()
	{
		pthread_mutex_destroy(&m_mutex);
	}
	void lock()
	{
		pthread_mutex_lock(&m_mutex);
	}
	void unlock()
	{
		pthread_mutex_unlock(&m_mutex);
	}
private:
	pthread_mutex_t m_mutex;	
};

CLock lk;
class CSingle_lh{
public:
	//1.使用mutex作为成员变量进行加锁
	static CSingle_lh* getInstance()
	{
		if (NULL == m_pins)
		{
			//当instance等于NULL是才使用加锁机制
			/*
				2次检查instance是否等于NULL,
			只有在第一次创建对象的时候进行加锁,当Instance不为空即对象已经存在的时候就不需要进行加锁的操作。
			第一次是防止每次都进来都加锁、释放锁
			第二次检查是否进行new对象
			*/
			pthread_mutex_lock(&m_mutex);
			if (NULL == m_pins)
			{
				m_pins = new CSingle_lh;
				m_cnt++;
			}
			pthread_mutex_unlock(&m_mutex);
		}

		return m_pins;
	}
	
	//申请个加锁类对象进行加锁
	/*
	static CSingle_lh* getInstance()
	{
		if (NULL == m_pins)
		{
			lk.lock();
			if (NULL == m_pins)
			{
				m_pins = new CSingle_lh;
				m_cnt++;
			}
			lk.unlock();
		}
		
		return m_pins;
	}
	*/
	static void printCnt()//测试函数
	{
		cout<<"m_cnt:"<<m_cnt<<"m_pins:"<<m_pins<<endl;
	}
	//释放资源函数
	static CSingle_lh* releaseInstance()
	{
		if (m_pins != NULL)
		{
			delete m_pins;
			m_pins = NULL;
		}
		return m_pins;
	}
private:	
	//构造函数设置为私有防止类外客户创建新对象
	CSingle_lh()
	{
		m_cnt = 0;
		m_pins = NULL;
		sleep(2);
	}
	//拷贝构造函数和赋值重载函数设置私有防止类外客户创建新和赋值对象
	CSingle_lh(const CSingle_lh& cs){;}
	CSingle_lh& operator=(const CSingle_lh& cs){;}
	
private:
	static CSingle_lh* m_pins;
	static int m_cnt;
	static pthread_mutex_t m_mutex;
};

//静态成员变量类中声明,类外初始化
int CSingle_lh::m_cnt = 0;
CSingle_lh* CSingle_lh::m_pins = NULL;
pthread_mutex_t CSingle_lh::m_mutex  = PTHREAD_MUTEX_INITIALIZER;

//单线程	
void test1()
{
	CSingle_lh* pins = CSingle_lh::getInstance();
	pins->printCnt();
	pins->releaseInstance();
}


void* func(void* arg)
{
	CSingle_lh* pins = CSingle_lh::getInstance();
	pins->printCnt();
	pins->releaseInstance();
}


//多线程
void test2()
{
	int i = 0;
	pthread_t id[10];
	for(i = 0; i<10; i++)
	{
		pthread_create(&id[i], NULL, func, NULL);
	}
	
	for(i = 0; i<10; i++)
	{
		pthread_join(id[i], NULL);
	}
}


int main()
{
	//test1();
	test2();
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值