千家信息网

Java的单例模式如何实现

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要介绍"Java的单例模式如何实现"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Java的单例模式如何实现"文章能帮助大家解决问题。什么是单例模式单
千家信息网最后更新 2026年11月04日Java的单例模式如何实现

这篇文章主要介绍"Java的单例模式如何实现"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Java的单例模式如何实现"文章能帮助大家解决问题。

什么是单例模式

  • 单例模式(Singleton Pattern)是一个比较简单的模式,实际应用很广泛,比如 Spring 中的Bean实例就是一个单例对象。

  • 定义:确保某一个类 只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式的优缺点

优点

  • 只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。

  • 单例模式可以避免对资源的多重占用,例如一个写文件动作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。

  • 单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。

缺点

  • 单例模式一般没有接口,很难扩展(根据环境而定)。

  • 单例模式与单一职责原则有冲突。一个类应该只实现一个逻辑,而不关心是否是单例的。

单例模式的实现

  • 单例模式有很多的实现方式,但是各种实现的方式都有其优缺点,下面来看看各种的实现方式。

  • 单例模式的实现满足以下几点:构造方法私有。有一个静态方法获取该类的实例。该类保证只有一个实例。

懒汉式

  • 懒汉式是当用到这个对象的时候才会创建。

  • 懒汉式,在需要单例模式类实例时它才创建出来给你(因为很懒)。

  • 优点:只有用到的时候才会创建这个对象,因此节省资源。

  • 简单的实现如下:

/**  *Singleton类,单例模式类,在类加载时便会创建一个私有静态变量instance,也就是该类的实  *例,再通过公共接口getInstance()来发布该实例  */public class Singleton {      private static Singleton instance;    //私有化构造方法防止外界new对象    private Singleton (){

}


//公有化静态函数,对外暴露单例对象的接口


public static Singleton getInstance() {


if (instance == null) {


instance = new Singleton();


}


return instance;


}


}

但是这种方式并不能保证这是唯一的单例,在高并发访问下,多个线程同时访问到这个单例时,还是有可能不能保证这个类就是单例的

为了保证线程安全,我们可以加锁,给这个getInstance()方法加上线程同步锁synchronize具体实现如下:

public class Singleton {      private static Singleton instance;      private Singleton (){            }      public static synchronized Singleton getInstance() {      if (instance == null) {          instance = new Singleton();      }      return instance;      }  }

但是这种方式一旦加锁,虽然可以保证其实单例且线程安全的,但是在高并发访问下性能必然是受到影响,多个线程都需要用到该单例时,就无法保证速度,需要同步地等待这个单例使用完回到JVM中的堆区(Heap)才可以继续使用这个单例,效率十分的低。

还有一种是双重检查式,两次判断

Double Check Lock(DCL)方式实现单例模式

public class Singleton{    private volatile static Singleton instance;    private Singleton(){            }    public static Singleton getInstance(){        if(instance == null){            synchronized (Singleton.class){                if(instance == null){                    instance = new Singleton();                }            }        }        return instance;    }}

我们可以看到getInstance中对instance进行了两次判断是否为空,第一次判断主要是为了避免不必要的同步问题,第二次判断则是为了在null的情况下创建实例,因为在某些情况下会出现失效问题即DCL失效问题,可以使用volatile关键字处理这个问题,但是同样的,使用了volatile关键字也会对性能有一定的影响。但是优点在于资源利用率高,第一次执行getInstance时对象才被实例化,但是DCL也因为第一次加载时反应慢,所以在高并发情况下也会有一定的缺陷。

饿汉式

  • 饿汉式和懒汉式恰巧相反,在类加载的时候就创建实例。

  • 单例模式类迫不及待的想要创建实例了(因为饿了)

  • 优点:还没用到就创建,浪费资源。

  • 缺点:在类加载的时候就创建,线程安全。

  • 实现如下:

/**  *这种方式在类加载时就完成了初始化,所以类加载较慢,但是获取对象的速度快。这种方式  *基于类加载机制,避免了多线程的同步问题。如果从来没有使用过这个实例,则会造成内存  *的浪费。  */public class Singleton {      private static Singleton instance = new Singleton();      private Singleton (){            }      public static Singleton getInstance() {            return instance;      }  }

匿名内部类/静态内部类

  • 利用静态变量、静态代码块、静态方法都是在类加载的时候只加载一次的原理。

  • 实现如下

public class Singleton {    private static Singleton instance;    //静态块在类加载时会被执行,也就创建了Singleton类实例    static{        instance = new Singleton();    }    private Singleton (){        }      public static final Singleton getInstance() {             return SingletonHolder.INSTANCE;      }  }
/**  *Java静态内部类的特性是,加载的时候不会加载内部静态类,使用的时候才会进行加载。  *第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚  *拟机加载SingletonHolder并初始化sInstance。这样不仅能确保线程安全,也能保证  *Singleton类的唯一性。所以,推荐使用静态内部类单例模式  */public class Singleton {      private static class SingletonHolder {       private static final Singleton INSTANCE = new Singleton();      }    private Singleton (){        }      public static final Singleton getInstance() {              return SingletonHolder.INSTANCE;      }  }

枚举单例模式

/**  *默认枚举实例的创建是线程安全的,并且在任何情况下都是单例。  *枚举单例的有点就是简单,缺点是可读性不高。  */public enum Singleton {    //外部调用由原来的Singleton.getInstance变成了Singleton.INSTANCE了。    INSTANCE;}

总结

单例模式是运用频率很高的模式,在我们客户端通常是没有高并发的情况,所以选择哪种方式并不会有太大的影响。出于效率考虑,推荐使用静态内部类的单例模式和DCL的单例模式。

优点:

  • 由于单例模式在内存中只有一个实例,减少内存开支,特别是一个对象需要频繁创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就十分明显。

  • 由于单例模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可通过在应用启动时直接产生一个单例对象,然后用永久驻留的方式解决。

  • 单例模式可以避免对资源的多重占用,如一个文件的操作,由于只有一个实例存在内存中,避免对同一个资源文件的同时操作。

  • 单例模式可以在系统设置全局的访问点,优化和共享资源访问。例如,可以设计一个单例类,负责所有数据表的映射处理。

缺点:

  • 单例模式一般没有接口,扩展很困难,除非修改代码。

  • 单例对象如果持有Context,那么很容易引发内存泄露,此时需要注意传递给单例对象的Context最好是Application Context。

  • 不适合用于变化频繁的对象;如果实例化的对象长时间不被利用,系统会认为该对象是垃圾而被回收,这可能会导致对象状态的丢失;

使用场景

  • 网站访问量计数器。

  • 项目中用于读取配置文件的类。

  • Spring中,每个Bean默认都是单例的,这样便于Spring容器进行管理。

关于"Java的单例模式如何实现"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注行业资讯频道,小编每天都会为大家更新不同的知识点。

模式 实例 对象 静态 方式 资源 线程 只有 内存 方法 时候 保证 问题 安全 优点 情况 文件 第一次 系统 性能 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 耶加雪菲 上海挚品互联网科技有限公司 伟宏互联网科技 A股互联网金融科技公司 互联网科技金融 互联网金融公司科技 互联网科技作文 紫鲸互联网科技 火传媒上海互联网科技 成都狮子座互联网科技 崇明区互联网教育科技诚信经营 华夏互联网科技业 成都互联网科技公司工作好不好 开一家科技互联网公司需要多少钱 烟台灵鸽互联网科技有限公司 山东星卡互联网科技有限公司官网 北京市互联网新科技 中国新注册互联网科技 瑞安市蟠桃会互联网科技有限公司 互联网科技自媒体灵感 互联网最新的科技有限公司 中国最先进互联网科技公司 华中科技有哪些互联网大佬 承德科技产业互联网发展 广州市恰铎互联网科技有限公司 深圳市优智互联网科技有限公司 燊美集互联网科技有限公司 区块链结合互联网科技 互联网公司属于科技吗 科技互联网企业在行动
0