singleton模式属于创建型设计模式。其作用是在程序设计中,对于某一个类而言,全局只能存在一个实例对象。

下面以C++为例,对单例模式进行说明:

1. 最基本单例模式(单线程)

 class Singleton1{
private:
static Singleton1 instance;
Singleton1(){} //构造函数
public:
static Singleton1 get_instance(){
if (Singleton1.instance==nullptr){ //若当前唯一实例为空,则创建新对象返回
instance=Singleton1();
}
return instance;
}
};

存在问题:在单线程下,只有instance == null 时,才会创建新对象,其余时间返回。但是对于多线程访问时,当两个或多个线程同时访问到instance==null,若判断成立,多个线程会分别实例化对象,这时程序就不满足单例条件了。

2.多线程的单例模式

针对上述问题,要在多线程中保证单例,就要进行线程同步控制,C++中使用mutex类族进行同步控制。

class Singleton2{
private:
static Singleton2 instance;
static std::mutex mutex_var;
Singleton2(){}
public:
static Singleton2 get_instance(){
mutex_var.lock(); //互斥量加锁进行线程同步
if (instance==nullptr){
instance=Singleton2();
}
mutex_var.unlock(); //互斥量解锁
return instance;
}
};

存在问题:线程安全,但程序效率不高。注意,此前讨论的出现的不满足单例的情况只出现在首次实例化对象时,但现在的程序在每次通过ger_instance函数访问时,都会进行加解锁操作,,加锁操作是十分耗时的,从而导致程序效率变低。

3.多线程下高效的单例模式

解决方法:仅在第一次实例化的时候加锁,其他时刻不加锁,提高程序效率。

class Singleton3{
private:
static Singleton3 instance;
static std::mutex mutex_var;
Singleton3(){}
public:
static Singleton3 get_instance(){
if (instance==nullptr) //外层多一次判断,如果单例已经存在,就不再进行加锁操作
{
mutex_var.lock(); //互斥量加锁进行线程同步
if (instance==nullptr){
instance=Singleton3();
}
mutex_var.unlock(); //互斥量解锁
}
return instance;
}
};

关于懒汉式和饿汉式的讨论

饿汉式:单例实例在类装载时就构建,急切初始化。(预先加载法)

懒汉式:单例实例在第一次被使用时构建,延迟初始化。(上述实现都是懒汉式的)。

这两类单例模式的区别在于实例化的时机不同。

饿汉式

优点:线程安全,在类加载的同时创建一个静态对象,调用时反应快。缺点:由于是提前定义,可能在全局程序中都没有使用这个实例,资源利用率不高。

懒汉式

优点:资源效率高,只要不用到该实例就不会被实例化。缺点:第一次加载速度不快。

两种方式各有优劣,针对不同的场景进行选择,一般情况下,使用饿汉式更多一些。

最新文章

  1. 微信小程序二维码推广统计
  2. HDU-2296 Ring(AC自动机+DP)
  3. DIOCP单元文件应用场景
  4. Ext-ajax请求数据
  5. mac上安装homebrew
  6. VS中引用第三方库的方法(配置sqlite数据库)
  7. python中将字符串转化为本地变量
  8. iOS App集成Apple Pay教程(附示例代码)
  9. node.js学习系列(一)
  10. IO (三)
  11. idea 配置git
  12. ORM 多表操作查询及增删改查
  13. 再议mysql 主从配置
  14. CAAnimation临时取消动画,永久取消动画
  15. sql语句执行出错:Incorrect integer value: '' for column 'id' at row 1
  16. oc的静态函数static
  17. IOS上z-index和fixed定位无效
  18. Windows改桌面文件路径
  19. SpringInAction--SpringMvc高级技术(servlet、filter、multipart)
  20. aspnetcore 认证相关类简要说明一

热门文章

  1. WebSocket实现Java后台消息推送
  2. [20190918]关于函数索引问题.txt
  3. 获取BOM标准用量
  4. [Go] 使用go mod安装beego
  5. Java重定向标准输入/输出
  6. 8.Python网络编程_多线程死锁
  7. 201871010111-刘佳华《面向对象程序设计(java)》第十一周学习总结
  8. luoguP2178 [NOI2015]品酒大会(后缀数组做法)
  9. [LeetCode] 238. Product of Array Except Self 除本身之外的数组之积
  10. win10挂载efi分区