线程安全的单例模式

线程安全的单例模式:
单例模式:属于创建类型的一种常用的软件设计模式,通过单例模式创建的类在当前进程中只有一个实例,一份资源只能被申请加载一次。
如何实现

  1. 饿汉模式:资源在程序初始化的时候就去加载,后边使用的时候直接使用,使用会非常流畅,但是有可能会加载上根本用不到的资源,而且程序初始化的时间也会较慢

  2. 懒汉模式:在进行资源的使用时,缺少这个资源才去加载,程序初始化的速度比较快,但是初次加载某个模块时会比较慢,因为这时候需要加载相应的资源。

饿汉模式实现方式:
使用static将某成员变量定义为静态成员变量,这样所有对象共用同一份资源,并且在程序初始化的时候就会加载资源,不涉及线程安全

代码:

class single_instance{
	
public:

	int* get_instance()
	{
		return &_data;	
	}


private:
	static int _data;
};
int single_instance::_data=10;


int main()
{
	single_instance a;
	single_instance b;

	printf("a:%d-----%p\n",*(a.get_instance()),a.get_instance());
	printf("b:%d-----%p\n",*(b.get_instance()),b.get_instance());

	return 0;
	
}

运行结果:
在这里插入图片描述
可以看到a和b两个对象使用的都是同一个数据资源

懒汉模式实现方式:

  1. 使用static保证所有对象使用同一份资源
  2. 使用volatile防止编译器过度优化
  3. 实现线程安全,保证资源判断及申请过程都是安全的
  4. 外部进行二次判断,避免资源已经加载成功多次获取锁资源,以及所带来的锁冲突

代码:

pthread_mutex_t mutex;
class single_instance{
	
public:
	volatile int* get_instance()
	{
		if(_data==NULL)
		{
			pthread_mutex_lock(&mutex);
			if(_data==NULL)
			{
				_data=new int;
				*_data=10;
			}
			pthread_mutex_unlock(&mutex);
		}
		return _data;
		
	}


private:
	volatile static int *_data;
};

volatile int*  single_instance:: _data=NULL;

int main()
{
	pthread_mutex_init(&mutex,NULL);
	single_instance a;
	single_instance b;

	printf("a:%d-%p\n", *(a.get_instance()), a.get_instance()); 
	printf("b:%d-%p\n", *(b.get_instance()), b.get_instance());
	
	pthread_mutex_destroy(&mutex);
	return 0;
}

运行结果:
在这里插入图片描述
对象a在需要使用数据时,加载了数据,b对象在使用时直接使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来解答您的问题。 首先,工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式,而单例模式则是一种保证一个类只有一个实例的设计模式。 在 C# ,我们可以将这两种模式结合使用来操作数据库。具体实现步骤如下: 1. 创建一个接口 IDbHelper,用于定义数据库操作的方法。 ```csharp interface IDbHelper { void Connect(); void Execute(string sql); } ``` 2. 创建一个工厂类 DbFactory,用于创建 IDbHelper 接口的实例。 ```csharp class DbFactory { private static IDbHelper instance = null; public static IDbHelper GetInstance() { if (instance == null) { instance = new SqlDbHelper(); // 这里以 SqlServer 数据库为例 } return instance; } } ``` 3. 创建一个单例类 SqlDbHelper,实现 IDbHelper 接口的方法。 ```csharp class SqlDbHelper : IDbHelper { private static SqlDbHelper instance = null; private SqlConnection conn = null; private SqlCommand cmd = null; private SqlDbHelper() { // 连接数据库 conn = new SqlConnection("数据库连接字符串"); conn.Open(); // 创建 Command 对象 cmd = new SqlCommand(); cmd.Connection = conn; } public static SqlDbHelper GetInstance() { if (instance == null) { instance = new SqlDbHelper(); } return instance; } public void Connect() { // 连接数据库 conn.Open(); } public void Execute(string sql) { // 执行 SQL 语句 cmd.CommandText = sql; cmd.ExecuteNonQuery(); } } ``` 4. 使用示例: ```csharp // 获取 SqlDbHelper 实例 IDbHelper dbHelper = DbFactory.GetInstance(); // 连接数据库 dbHelper.Connect(); // 执行 SQL 语句 dbHelper.Execute("SELECT * FROM user"); ``` 当我们需要操作数据库时,只需要通过工厂类获取 IDbHelper 接口的实例,然后调用其方法即可。由于 SqlDbHelper 类采用了单例模式,因此每次获取到的实例都是同一个,避免了频繁创建对象的开销,提高了程序的性能。 希望这个示例能够帮助您理解工厂模式和单例模式的使用,以及如何在 C# 操作数据库。如果您有其他问题,欢迎随时咨询我。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值