前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原来要这么实现单例模式

原来要这么实现单例模式

作者头像
灬沙师弟
发布2023-03-07 08:42:12
2060
发布2023-03-07 08:42:12
举报
文章被收录于专栏:Java面试教程

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

一.禁止new创建多个实例

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

饿汉式

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

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

懒汉式

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

代码语言:javascript
复制
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保证了只会实例化一次,所以是线程安全的。

代码语言:javascript
复制
public class Singleton{
  private Singleton(){}
 
  private static class SingleTonHoler{
     private static Singleton INSTANCE = new Singleton();
 }
 
  public static Singleton getInstance(){
    return SingleTonHoler.INSTANCE;
  }
}

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

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

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

三.总结

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-02-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java面试教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.禁止new创建多个实例
    • 饿汉式
      • 懒汉式
        • 静态内部类
        • 二. 防止反射创建多个实例
        • 三.总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档