原来要这么实现单例模式

简介: 原来要这么实现单例模式

单例模式:大家应该都不陌生,就是保证jvm进程里一个类只会对应一个实例对象。有很多方法可以实现单例模式,但是哪一种是最安全的,不能通过非法的手段,创建多个实例对象,比如通过反射,new的方式创建多个。我们今天就来学习一下。

一.禁止new创建多个实例

通过把构造函数的修饰符设置为private, 禁止通过new的方法实例化,只能调用提供的方法获取到实例对象,确保获取到的实例对象都是同一个,这样来保证单例。

饿汉式

Singleton 构造函数是private的,Singleton类在加载完成就会实例化,所以即使没有使用到这个类,也会进行实例化。优点是比较简单,线程安全,但是缺点也很明显如果这个类实例化比较耗时,在类加载的时间就会很长,如果占用内存,即使没有用到这个实例也会占用大量内存。

public class Singleton {  //静态代码块
 //私有化构造器
 private Singleton() {}
 //内部创建对象实例
 private  static Singleton instance;
 static { // 在静态代码块中,创建单例对象
  instance = new Singleton();
 }
 //对外公有的静态方法
 public static Singleton getInstance() {
  return instance;
 }
}

懒汉式

饿汉式是需要的时候才创建实例对象,一般结合双重检查来实现,否则会导致线程不安全,就是多个线程调用getInstance方法时,可能会获取到不同的实例对象。需要注意的是Singleton对象还需要用volatile来修饰,这样才能避免指令重排,指令重排可能会导致获取到的Singleton对象还没有实例化完成。

public class Singleton { //双重检查
 private static volatile Singleton instance;
 private Singleton() {}
 public static synchronized Singleton getInstance() {
  if(instance == null) { //判断是否实例化
   synchronized (Singleton.class) {
    if(instance == null) {
     instance = new Singleton();
    }
   }
  }
  return instance; //否则直接return
 }
}

静态内部类

这个声明一个静态内部类的形式,既可以实现懒汉式的效果,只有调用了getInstance方法,SingleTonHoler才会初始化;也可以实现线程安全的效果,静态内部类把Singleton对象声明为static类型,在类加载的时候会实例化,且jvm保证了只会实例化一次,所以是线程安全的。

public class Singleton{
  private Singleton(){}
  private static class SingleTonHoler{
     private static Singleton INSTANCE = new Singleton();
 }
  public static Singleton getInstance(){
    return SingleTonHoler.INSTANCE;
  }
}

二. 防止反射创建多个实例

上面的几种方式都可以多线程的情况下,类只能实现一次,但是都是可以通过反射的方法来创建多个实例对象的,那有没有一种既可以防止反射,又可以保证多线程安全的单例实现方法呢?有的,就是通过枚举的方式实现。

enum Singleton {
 INSTANCE; //属性
 public void say() {
  System.out.println("关注java面试教程 学习更多java知识");
 }
}

三.总结

我们学习了怎么来创建一个安全可靠的单例模式,如果不需要防止反射的情况下,可以通过静态内部类的方法实现,否则,推荐使用枚举的形式来实现单例。

相关文章
|
6月前
|
设计模式 安全 Java
单例模式分享
单例模式分享
29 0
|
7月前
|
C++
【C++ 单例模式】
【C++ 单例模式】
|
设计模式 Java Spring
什么场景要使用单例模式,什么场景不能使用?
经常有小伙伴问我,设计模式学了这么久,每次看到概念也都能理解。但是,就是不知道怎么用,在哪里能用?我告诉大家,设计模式,不是为了要用而用的,而是作为前人总结下来的经验,等到哪天需要用的时候,你能想起来为你所用。
110 0
|
设计模式 安全 Java
回顾一下单例模式
回顾一下单例模式
|
数据采集 设计模式 算法
大佬,人人都说精通的单例模式,你精通了吗
大佬,人人都说精通的单例模式,你精通了吗
91 0
大佬,人人都说精通的单例模式,你精通了吗
机房重构之单例模式的应用
机房重构之单例模式的应用
|
开发框架 安全 Java
单例模式的应用(1)
单例模式的应用(1)
148 0
|
安全 Java 容器
单例模式的应用(3)
单例模式的应用(3)
178 0
|
设计模式 Java
单例模式的应用(2)
单例模式的应用(2)
133 0
|
存储 设计模式 缓存
浅谈单例模式
本文描述设计模式中的单例模式