单例模式(Singleton Pattern)

时间:2024-04-17 23:34:18

意图

保证一个类仅有一个实例,并提供一个该实例的全局访问点

可将一个实例扩展到n个实例。限定某类最多只能创建n个实例。

双重锁定实现单例模式

C#

public sealed class Singleton
{
private static volatile Singleton instance = null;
private static readonly object lockHelper = new object(); private Singleton() { } public static Singleton Instance
{
get
{
if (instance == null)
{
lock (lockHelper)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}

解决了线程并发问题,同时避免在每个 Instance 属性方法的调用中都出现独占锁定。还实现了惰性实例化。

volatile修饰:编译器在编译代码的时候会对代码的顺序进行微调,用volatile修饰保证了严格意义的顺序。一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

 JAVA的双重校验单例模式

public final class Singleton {
private volatile static Singleton singleton;
private Singleton() {
}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}

利用类加载器

没有懒加载,利用类装载时实例化,避开了多线程的问题

C#

public sealed class Singleton
{
private static Singleton instance = new Singleton();
static private Singleton() { }
public static Singleton getInstance()
{
return instance;
}
}

java

public final class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}

类加载器+内部类/嵌套类

同样采用类加载器避开多线程同步问题,这里却可以只在内部类/嵌套类被调用时加载。优于上一方法。

C#的嵌套类

public sealed class Singleton
{
private Singleton() { }
public static Singleton getInstance() {
return Nested.instance;
}
private class Nested
{
internal static readonly Singleton instance = new Singleton();
}
}

JAVA的静态内部类

public final class Singleton {
private Singleton() { }
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
}

java利用枚举

java的枚举常量本身就是实例,而且枚举不能在运行时实例化。

public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
class whateverClass{
}
}

  

swift 中单例模式

swift从1.2开始,类中可以使用static修饰词,自带懒加载特性

class Singleton{
static let instance = Singleton()
}