问题描述
什么是单例
单例 Singleton 是设计模式的一种,其特点是只提供唯一一个类的实例,具有全局变量的特点即提供一个访问它的全局访问点,该实例被所有程序模块共享。这个类在全局只有唯一的一个实例对象,在所有位置都可以通过该类提供的接口访问到这个唯一实例。
单例优缺点
单例类主要解决了一个全局使用的类的频繁的创建与销毁。
-
优点:
- 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例;
- 2、避免对资源的多重占用。
-
缺点:
- 单例类没有接口,不能继承。
C++实现单例模式要点
-
构造函数需私有化
- 将该类的构造函数私有化,目的是禁止其他程序创建该类的对象,同时也是为了提醒查看代码的人我这里是在使用单例模式,防止他人将这里任意修改。此时,需要提供一个可访问类自定义对象的类成员方法(对外提供该对象的访问方式)。即把构造函数设置为private可以防止用户自己定义实例。
-
指向本身实例的类属性为静态
指向自己实例的私有引用在被类方法(Getinstance)调用时被初始化,只有静态成员变量才能在没有创建对象时进行初始化,并且类的静态成员在第一次使用时不会再被初始化,保证了单例,因此设置为静态。 -
通过一个static静态成员方法返回唯一的对象实例
通过类方法(GetInstance) 获取instance,类属性instance为静态的(static),则需要类的静态方法才能调用,因此该类方法应设为静态的。通过一个静态成员函数GetInstance来获取实例。静态成员函数可以在不定义对象的情况下调用。
单例应用场景
-
优点
(1)在单利模式中,活动的实例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例,这样就防止其他对象自己实例化,确保所有对象都访问一个实例
(2)单例模式中的类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。
(3)提供了对唯一实例的受控访问
(4)避免对共享资源的多重使用
(5)由于在系统只存在一个对象,因此可以节约资源,当需要偏饭创建和销毁对象时,单例模式无疑可以提高系统性能 -
缺点
(1)不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。
(2)滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。
(3)由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。 -
应用场景
(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。
(2)控制资源的情况下,方便资源之间的互相通信。如线程池等。
具体运用场景
- 最经典的使用场景是公用缓存,由一个线程周期性地写,由多个线程读取,此时就可以用单例模式来保证不同线程写和读的是同一个实例。
- 设备管理器,系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动;
- 数据池,用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取;
饿汉式:在单例类定义时即实例化
饿汉式指的是无论会不会有人调用getInstance获取实例,都会事先把这个实例给创建好。饿汉式可以通过在类里加入一个静态成员变量来实现(注意C++的静态成员变量必须在类外初始化)
public class One {
//私有化构造方法使得该诶无法通过外部new 进行实例化
private One(){}
//准备一个类属性,指向一个实例化对象。 因为是类属性,所以只有一个
private static One instance = new One();
public static One getInstance(){
return instance;
}
}
//One 应该只有一只,通过私有化其构造方法,使得外部无法通过new 得到新的实例。
//One 提供了一个public static的getInstance方法,外部调用者通过该方法获取的对象,而且每一次都是获取同一个对象。 从而达到单例的目的。
饿汉式:多线程安全问题
饿汉单例模式中,单例对象定义成了一个static静态对象,它是在程序启动时,main函数运行之前就初始化好的,因此不存在线程安全问题,可以放心的在多线程环境中使用。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)