设计模式

单例模式

一个类只允许创建一个对 象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。

如何实现一个单例

  1. 构造函数需要是 private 访问权限的,这样才能避免外部通过 new 创建实例;
  2. 考虑对象创建时的线程安全问题;
  3. 考虑是否支持延迟加载;
  4. 考虑 getInstance() 性能是否高(是否加锁)
  • 饿汉式
    在类加载的时候,instance 静态实例就已经创建并初始化好了,所以,instance 实例的创建过程是线程安全的。不过,这样的实现方式不支持延迟加载(在真正用到 IdGenerator 的时候,再创建实例)。
  • 懒汉式
    懒汉式相对于饿汉式的优势是支持延迟加载。这种实现方式会导致频繁加锁、释放锁,以及并发度低等问题,频繁的调用会产生性能瓶颈。
  • 双重检测
    双重检测实现方式既支持延迟加载、又支持高并发的单例实现方式。只要 instance 被创建 之后,再调用 getInstance() 函数都不会进入到加锁逻辑中。所以,这种实现方式解决了懒汉式并发度低的问题。
  • 静态内部类
    利用 Java 的静态内部类来实现单例。这种实现方式,既支持延迟加载,也支持高并发,实 现起来也比双重检测简单。
  • 枚举
    最简单的实现方式,基于枚举类型的单例实现。这种实现方式通过 Java 枚举类型本身的特 性,保证了实例创建的线程安全性和实例的唯一性。

集群环境下的单例:
把这个单例对象序列化并存储到外部共享存储区(比如文件)。进程在使用这个单例对象的时候,需要先从外部共享存储区中将它读取到内存,并反序列化成对象,然后再使用,使用完成之后还需要再存储回外部共享存储区。为了保证任何时刻在进程间都只有一份对象存在,一个进程在获取到对象之后,需要对对象加锁,避免其他进程再将其获取。在进程使用完这个对象之后,需要显式地将对象从内存中删除,并且释放对对象的加锁。

工厂模式

工厂模式分为三种更加细分的类型:简单工厂、工厂方法和抽象工厂。

简单工厂