线程安全延迟初始化方案 #10

Posted 5 years ago · 1 mins reading

Java

Initialization On Demand Holder idiom

java
public class InstanceFactory {
private static class InstanceHolder {
public static Instance instance = new Instance();
} public static Instance getInstance() {
return InstanceHolder.instance ;  // 这里将导致InstanceHolder类被初始化
}
}

DoubleCheckedLocking

java
public class SafeDoubleCheckedLocking {
private volatile static Instance instance;
public static Instance getInstance() {
if (instance == null) {
synchronized (SafeDoubleCheckedLocking.class) {
if (instance == null) instance = new Instance(); // instance为volatile,现在没问题了
}
}
return instance;
}
}

结语

字段延迟初始化降低了初始化类或创建实例的开销,但增加了访问被延迟初始化的字段 的开销。在大多数时候,正常的初始化要优于延迟初始化。如果确实需要对实例字段使用线程 安全的延迟初始化,请使用上面介绍的基于volatile的延迟初始化的方案;如果确实需要对静 态字段使用线程安全的延迟初始化,请使用上面介绍的基于类初始化的方案。

c++

c++中的常见单例

cpp
class Singleton {
public:
static Singleton &GetInstance();
private:
Singleton();
~Singleton();
Singleton(const Singleton &);
const Singleton &opertor = (const Singleton &);
}
Singleton &Singleton::GetInstance() {
static Singleton instance;
return instance;
}

DoubleCheckedLocking

cpp
Singleton &Singleton::GetInstance() {
static Singleton *instance = nullptr;
if (!instance) {
Mutex mutex;
ScopedLock lock(&mutex);
if (!instance) {
instance = new Singleton();
}
}
return *instance;
}