# 单例模式

## 定义

保证某个类在全局只有一个实例存在。

## 代码实现

### 饿汉模式

```
class Singleton {
    private static Singleton sInstance = new Singleton();

    //私有构造方法
    private Singleton() {
        
    }

    public static Singleton getInstance() {
        return sInstance;
    }
}
```

借助类加载机制避免了多线程重复创建实例问题，类加载时就进行初始化，没有实现懒加载。

### 懒汉模式（线程不安全）

```
class Singleton {
    private static Singleton sInstance;

    //私有构造方法
    private Singleton() {
        
    }

    public static Singleton getInstance() {
        if (sInstance == null) {
            //多个线程进入判断会创建不同的实例
            sInstance = new Singleton();
        }
        return sInstance;
    }
}
```

实现了延迟初始化，但是多线程访问会重复创建实例。

### 懒汉模式（互斥锁）

```
class Singleton {
    private static Singleton sInstance;

    //私有构造方法
    private Singleton() {
        
    }

    //使用 synchronized 保证互斥
    public static synchronized Singleton getInstance() {
        if (sInstance == null) {
            sInstance = new Singleton();
        }
        return sInstance;
    }
}
```

使用互斥锁避免的并发问题，但是由于每次获取实例都要加锁（大部分情况不需要这么做），导致性能较低。

### 懒汉模式（双重null检查）

```
class Singleton {
    private static volatile Singleton sInstance;

    // 私有构造方法
    private Singleton() {

    }

    public static Singleton getInstance() {
        if (sInstance == null) {
            //如果多个线程进入判断，通过加锁保证互斥
            synchronized (Singleton.class) {
                if (sInstance == null) {
                    sInstance = new Singleton();
                }
            }
        }
        return sInstance;
    }
}
```

既避免了并发问题，又避免了互斥锁写法带来的性能问题。

通过 volatile 关键字禁止指令重排和保证可见性。

### 静态内部类

```
class Singleton {
    // 私有构造方法
    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
}
```

只有调用getInstance()方法时才会加载静态内部类并创建静态常量，所以实现了延迟加载；通过类加载机制避免了多线程并发问题。
