📘
InterviewBase
  • 写在前面
  • 数据结构与算法
    • test
  • 计算机网络
    • test
  • 操作系统
  • 软件工程
    • 设计模式
      • 观察者模式
      • 单例模式
Powered by GitBook
On this page
  • 定义
  • 代码实现
  • 饿汉模式
  • 懒汉模式(线程不安全)
  • 懒汉模式(互斥锁)
  • 懒汉模式(双重null检查)
  • 静态内部类

Was this helpful?

  1. 软件工程
  2. 设计模式

单例模式

定义

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

代码实现

饿汉模式

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()方法时才会加载静态内部类并创建静态常量,所以实现了延迟加载;通过类加载机制避免了多线程并发问题。

Previous观察者模式

Last updated 5 years ago

Was this helpful?