单例模式 Singleton

面向对象的设计模式,是在特定场景下常用而有效的设计,优点在于代码有效,易读,有利于程序员复用,维护。

单例模式 (Singleton)

单例模式class diagram

单例模式是23种GoF设计模式中的一种,主要用来解决以下问题:

  1. 如何保证一个类只有一个实例?
  2. 如何让访问单个实例变得简单?
  3. 如何让类控制实例化
  4. 如何限制一个类的实例数量?

单例模式使用下列方式解决上述问题:

  1. 隐藏构造器
  2. 定义一个public static operation ( getInstance() ) 来返回单例

特点:这种设计模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点

使用场景:

1. abstract factory,builder和prototype patterns 可以利用singletons 来实现
2. Facade objects通常就是 singletons
3. State objects通常也是singletons
4. 用于全局变量,因为不会污染全局namespace,而且允许延迟装载资源。

案例:例如服务器的配置文件由唯一的单例类实例来读取,其他类再通过单例类实例来获取配置信息。

缺陷:多线程下,并发线程对单例类的实例化可能产生多个实例。因此需要为实例化指示变量加上一个互斥锁。

单例几种写法

1. 饿汉(静态常量)

/*
 * A simple implementation of singleton pattern
 * using final static instance
 */
public class SingletonH {
  //ensure only one instance of the singleton class ever exists
  private final static SingletonH INSTANCE = new SingletonH();

  private SingletonH(){}
  //provide global access to that instance
  public static SingletonH getInstance(){
    return INSTANCE;
  }
}

饿汉直接预加载静态常量,方便但是占用资源。

2. 饿汉(静态代码块)

/*
 * A simple implementation of Singleton pattern
 * by using a static code block
 */

public class SingletonHSB{
  private static Singleton instance;
  static {
    instance = new SingletonHSB();
  }

  private SingletonHSB(){}

  public static SingletonHSB getInstance(){
    return instance;
  }
}

3. 静态内部类

/*
 * a simple implementation of Singletons by using
 * a static inner class
 *
 */
public class SingletonSIC {

  private SingletonSIC(){}

  private static class SingletonInstance {
    private static final SingletonSIC INSTANCE = new SingletonSIC();
  }

  public static SingletonSIC getInstance(){
    return SingletonInstance.INSTANCE;
  }
}

静态内部类实现延迟加载,因为只有当调用其静态成员时,才加载。

4. 枚举类

/*
 * a simple implementation of Singletons by using
 * an enum INSTANCE
 */
public enum SingletonEnum {
  INSTANCE;
  public void whateverMethod(){

  }
}

5. 双重检查

/* a simple implmentation of singletons by using
 * double check if an instance already exists
 */
public class SingletonDC{

  private volatile static SingletonDC singleton;

  private SingletonDC(){}

  public static SingletonDC getInstance(){
    if (singleton == null){
      synchronized (Singleton.class){
        if (singleton == null){
          singleton = new SingletonDC();
        }
      }
    }
    return singleton;
  }
}

双重检查减少了同步的部分性能损耗,当多个线程检查到实例已初始化后,直接返回实例。
为了让实例变量的初始化对多个线程同步可见,我们还需要使用volatile修饰变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值