什么是线程安全?
在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
如何保证线程安全?
- 给共享的资源加把锁,保证每个资源变量每时每刻至多被一个线程占用。
- 让线程也拥有资源,不用去共享进程中的资源。如: 使用threadlocal可以为每个线程的维护一个私有的本地变量。
什么是单例模式?
单例模式指在整个系统生命周期里,保证一个类只能产生一个实例,确保该类的唯一性。
单例模式分类
单例模式可以分为懒汉式和饿汉式,两者之间的区别在于创建实例的时间不同:
- 懒汉式:指系统运行中,实例并不存在,只有当需要使用该实例时,才会去创建并使用实例。(这种方式要考虑线程安全)
- 饿汉式:指系统一运行,就初始化创建实例,当需要时,直接调用即可。(本身就线程安全,没有多线程的问题)
单例类特点
- 构造函数和析构函数为private类型,目的禁止外部构造和析构
- 拷贝构造和赋值构造函数为private类型,目的是禁止外部拷贝和赋值,确保实例的唯一性
- 类里有个获取实例的静态函数,可以全局访问
特点与选择
- 懒汉式是以时间换空间,适应于访问量较小时;推荐使用内部静态变量的懒汉单例,代码量少
- 饿汉式是以空间换时间,适应于访问量较大时,或者线程比较多的的情况
普通懒汉式单例(线程不安全)
1 | /////////////////// 普通懒汉式实现 -- 线程不安全 ////////////////// |
加锁的懒汉式单例(线程安全)
1 | /////////////////// 加锁的懒汉式实现 ////////////////// |
内部静态变量的懒汉单例(C++11线程安全)
1 | /////////////////// 内部静态变量的懒汉实现 ////////////////// |
饿汉式单例(本身就是线程安全)
1 | ////////////////////////// 饿汉实现 ///////////////////// |