简单论述之单例模式分析

问题:

1.什么是单例模式?

单例模式是软件设计模式中的一种,它的核心结构只包含一个被称为单例的特殊类,通过单例模式保证系统中一个类只有一个实例。

对于系统中的许多类来说,只能有一个实例。比如:Windows系统资源管理器(如果不对对象唯一化,将会弹出多个窗口)

(1)窗口内容完全不一致 =》 内存资源浪费

(2)窗口内容不一致  =》 意味着在某一时刻,系统有多种状态 =》与实际不符

这就体现了唯一性 => 即一个类只有一个对象实例化

那么如何保证一个类只有一个实例,并且易于访问呢?


2.单例模式的实现及其要点?

(1)某一个类只有一个实例   =》 单例模式的类只实现私有的构造函数

(2)自行向系统实现提供该实例  =》该类实现一个静态的公有的函数用于创建或获取它本身的静态私有对象。

3.不说了,上代码


当我在main函数中创建sgn时,系统会先给sgn在堆上开辟内存,然后调用构造函数去构造对象,但由于构造函数是私有的,外部不能访问。但我们提供了一个静态的接口函数,当我们第一次访问时,就会在堆上开辟一个内存,然后将类类型的指针指向这块内存,调用构造函数构造对象,当我们再访问这个接口函数时,系统就会将指向这个对象的地址返回给我们,通过指针sgn去访问这个对象。

3.懒汉单例模式与恶汉单例模式

懒汉单例模式是在第一次获取时才产生,饿汉模式是在程序运行时就产生。代码如下:

 


饿汉模式不存在线程安全问题,因为在加载时就已经完成初始化。

懒汉式存在线程安全问题:

而懒汉模式需要判断_instance是否为空,这就产生了一些问题。


那如何解决这一问题呢?这里就要引入锁了。

4.锁

首先,数据的操作方式无非三种:读读、写写和读写。

而锁一般也根据线程的状态分为:互斥、读写锁(阻塞)和自旋锁(循环)

这里用到了linux下的互斥锁:


锁一般是个很重的东西,解锁开销也很大,所以这里加了双重判断是为了解决:

1.锁的开销

如果只有一个if,那么每次当系统执行到instance()这个函数时,都要进行加锁和解锁,而双重判断就避免了p不为空的情况。

2.避免线程安全问题

在加锁期间可以出现的问题。

5.总结


猜你喜欢

转载自blog.csdn.net/lixin_com/article/details/80214575
今日推荐