【设计模式】单例模式

概述

单例模式的英文原话是:Ensure a class has only one instance,and provide a global point of access to it。意思就是确保一个类只有一个实例存在,并提供一个全局访问点。正是因为单例模式有这样的特性,单例模式可以用在建立目录、数据库连接等需要单线程操作的场合,用于实现对系统资源的控制。

懒汉式单例类

特点:在第一次调用的时候实例化自己。

//在第一次调用的时候实例化自己
public class Singleton {
  //1.私有构造器
  private Singleton() {}

  //2.静态变量
  private static Singleton singleton = null;

  //3.静态方法
  public static Singleton getInstance() {
    if (Objects.isNull(singleton)) {
      singleton = new Singleton();
    }
    return singleton;
  }
}

缺点:线程不安全,并发环境下可能出现多个实例。

解决方案:

在静态方法上面加同步锁

特点:解决线程不安全问题,保证在并发环境下只会出现一个实例。

缺点:只有第一次执行该静态方法时,才真正需要同步。而实际上,每次执行该方法时,都会进行同步,会影响性能,毕竟99%的情况下是不需要同步的。

//在第一次调用的时候实例化自己
public class Singleton {
  //1.私有构造器
  private Singleton() {}

  //2.静态变量
  private static Singleton singleton = null;

  //3.静态方法
  //synchronize同步锁
  public static synchronized Singleton getInstance() {
    if (Objects.isNull(singleton)) {
      singleton = new Singleton();
    }
    return singleton;
  }
}
双重检查加锁

特点:保证了当静态变量被初始化成具体实例时,多个线程能正确地处理静态变量。

缺点:双重检查加锁不适用于Java 4或更早版本的Java。

//在第一次调用的时候实例化自己
public class Singleton {
  // 1.私有构造器
  private Singleton() {}

  // 2.静态变量
  private static volatile Singleton singleton = null;

  // 3.静态方法
  public static Singleton getInstance() {
    // 双重检查加锁
    if (Objects.isNull(singleton)) {
      synchronized (Singleton.class) {
        if (Objects.isNull(singleton)) {
          singleton = new Singleton();
        }
      }
    }
    return singleton;
  }
}

注:volatile关键字是为了确保当静态变量被初始化成具体实例时,多个线程正确地处理静态变量。

静态内部类
public class Singleton {
  //1.私有构造方法
  private Singleton() {}

  //2.静态内部类
  private static class LazyHolder {
    private static final Singleton INSTANCE = new Singleton();
  }

  //3.静态方法
  public static Singleton getInstance() {
    return LazyHolder.INSTANCE;
  }
}

饿汉式单例

特点:饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。

// 在类初始化时,已经自行实例化
public class Singleton {
  // 1.私有构造
  private Singleton() {}

  // 2.静态变量
  private static final Singleton single = new Singleton();

  // 3.静态方法
  public static Singleton getInstance() {
    return single;
  }
}

总结

  1. 单例模式能够确保在程序中一个类最多只有一个实例,并提供一个唯一的全局访问点
  2. 由于构造函数是私有的,所以单例类不能被继承
  3. 在Java中实现单例模式时需要私有的构造器一个静态方法一个静态变量
  4. Java 5以下版本时,双重检查加锁实现会失效
  5. 使用多个类加载器时,单例会失效而产生多个实例
  6. 使用JVM1.2或之前的版本,必须建立单例注册表,以免垃圾收集器将单例回收
  7. 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单例,以解决多线程的问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值