C++单例模式
单例饿汉式
- 加载类的时候初始化(不使用也会构造类,空间换时间)
#include <stdio.h>
#include <string>
class DriverManger
{
private:
long m_nDate;
int m_nDriverNum;
std::string m_strDriverInfo;
private:
// 私有构造函数,禁止new方式实例化
DriverManger(){printf("new DriverManger..
");}
// 私有析构,实例的生命周期是程序开始到结束,无需手动释放
~DriverManger(){printf("delete DriverManger..
");}
// 禁止拷贝构造和赋值操作符
DriverManger(DriverManger&)/*=delete*/;
const DriverManger& operator=(const DriverManger&)/*=delete*/;
static DriverManger instance;
public:
static DriverManger& GetInstance(void)
{
return instance;
}
};
//下面这个静态成员变量在类加载的时候就已经初始化好了
DriverManger DriverManger::instance;
int main(void)
{
printf("begin main..
");
DriverManger& driver1 = DriverManger::GetInstance();
DriverManger& driver2 = DriverManger::GetInstance();
printf("%p && %p",&driver1, &driver2);
return 0;
}
单例懒汉式
- 使用到时(调用getInstance方法)才构造类实例
- 多线程造成的实例不唯一
#include <stdio.h>
#include <string>
class DriverManger
{
private:
long m_nDate;
int m_nDriverNum;
std::string m_strDriverInfo;
static DriverManger* theDriver;
private:
// 私有构造函数,禁止new方式实例化
DriverManger(){}
// 禁止拷贝构造和赋值操作符
DriverManger(DriverManger&)/*=delete*/;
const DriverManger& operator=(const DriverManger&)/*=delete*/;
public:
static DriverManger* GetInstance(void)
{
if (nullptr == theDriver)
{
theDriver = new DriverManger();
}
return theDriver;
}
~DriverManger()
{
if (nullptr != theDriver)
{
delete theDriver;
}
}
};
DriverManger* DriverManger::theDriver = nullptr;
int main(void)
{
DriverManger* pDriver = DriverManger::GetInstance();
DriverManger* pDriver2 = DriverManger::GetInstance();
printf("%p && %p
", pDriver, pDriver2);
getchar();
return 0;
}
局部静态变量的单例懒汉式
- 使用局部静态变量的特性保证了线程安全
#include <stdio.h>
#include <string>
class DriverManger
{
private:
long m_nDate;
int m_nDriverNum;
std::string m_strDriverInfo;
private:
// 私有构造函数,禁止new方式实例化
DriverManger(){}
// 禁止拷贝构造和赋值操作符
DriverManger(DriverManger&)/*=delete*/;
const DriverManger& operator=(const DriverManger&)/*=delete*/;
public:
static DriverManger& GetInstance(void)
{
// 静态局部变量保证每次获取到唯一实例
static DriverManger driver;
return driver;
}
~DriverManger(){}
};
int main(void)
{
DriverManger& driver1 = DriverManger::GetInstance();
DriverManger& driver2 = DriverManger::GetInstance();
return 0;
}
JAVA单例模式
单例饿汉式
缺点是加载类就分配空间,浪费资源
- 构造器私有
- 提供外界可访问方法
public class Student {
// 构造私有,外界不能直接创建
private Student() {
}
// 类本身创建一个对象
//private外界不能干预对象的赋值
//static静态方法调用静态成员
private static Student s = new Student();
// 提供外界访问该对象的方法
//static静态外界可以直接通过类名访问
public static Student getStudent() {
return s;
}
public void show(){
System.out.println("hello");
}
}
单例懒汉式(方法锁保证线程安全)
- 效率低
public class Teacher {
private Teacher(){
}
private static Teacher t = null;
//同步方法保证线程安全,因为有可能多个线程同时进入判断语句中
public synchronized static Teacher getTeacher(){
if(t==null){
t = new Teacher();
}
return t;
}
}
双重检测的懒汉式
/**
* 线程安全的单例懒汉式
*/
public class ConcurrentSingle {
private ConcurrentSingle(){
}
// volatile防止 new 时的指令重排
private volatile static ConcurrentSingle theApp;
// 双重检测锁
public static ConcurrentSingle getTheApp() {
if (theApp == null) {
synchronized (ConcurrentSingle.class) {
if (theApp == null) {
theApp = new ConcurrentSingle(); // 可能指令重排
}
}
}
return theApp;
}
}
静态内部类单例模式
public class InnerSingle {
private InnerSingle() {
}
public InnerSingle getInstance() {
return Inner.HOLDER;
}
// 静态内部类
private static class Inner{
// 外部类的实例化对象
private static final InnerSingle HOLDER = new InnerSingle();
}
}
枚举实现单例
- 线程安全
- 可防止反射破坏
public enum EnumSingle {
INSTANCE;
private Resource resource;
EnumSingle() {
resource = new Resource();
}
public Resource getResource() {
return resource;
}
}
class Resource{
}
jdk中使用的单列模式
Runtime r = Runtime.getRuntime();
源码
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
...