首页 > 编程语言 >Java单例模式详解

Java单例模式详解

时间:2023-08-11 11:05:42浏览次数:39  
标签:Singleton Java private instance 详解 static 单例 public

Java单例模式详解

单例模式是设计模式中的一种,它确保某一个类只有一个实例,并提供一个全局点来访问这个实例。这在某些场景中是非常有用的,例如,配置管理、线程池、缓存、日志对象等。

1. 单例模式的基本原则:

  • 构造函数是私有的。
  • 有一个私有静态变量来保存类的唯一实例。
  • 有一个公有静态方法,供外界获取类的唯一实例。

2. 实现方法:

  • 饿汉式:在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。
javaCopy code
 public class Singleton {
     private static Singleton instance = new Singleton();
     
     private Singleton() {}
     
     public static Singleton getInstance() {
         return instance;
     }
 }
  • 懒汉式:在第一次调用时初始化并创建实例。需要注意线程安全。
javaCopy code
 public class Singleton {
     private static Singleton instance;
     
     private Singleton() {}
     
     public static synchronized Singleton getInstance() {
         if (instance == null) {
             instance = new Singleton();
         }
         return instance;
     }
 }

注意:上述方法使用了synchronized关键字来确保线程安全,但这会使方法同步,可能会影响性能。

  • 双重校验锁(Double-Checked Locking):结合了懒汉式和synchronized的优点,单例延迟初始化且线程安全,但需要注意volatile的使用。
javaCopy code
 public class Singleton {
     private static volatile Singleton instance;
     
     private Singleton() {}
     
     public static Singleton getInstance() {
         if (instance == null) {
             synchronized (Singleton.class) {
                 if (instance == null) {
                     instance = new Singleton();
                 }
             }
         }
         return instance;
     }
 }
  • 静态内部类:使用内部类的方式来实现单例,既保证了线程安全,又能够延迟加载。
javaCopy code
 public class Singleton {
     private Singleton() {}
     
     private static class SingletonHolder {
         private static final Singleton INSTANCE = new Singleton();
     }
     
     public static Singleton getInstance() {
         return SingletonHolder.INSTANCE;
     }
 }
  • 枚举方式:使用枚举来实现单例是推荐的方法,因为它既保证线程安全,又防止反序列化创建另一个实例。
javaCopy code
 public enum Singleton {
     INSTANCE;
     
     public void someMethod() {
         // some singleton behavior
     }
 }

3. 注意事项和陷阱:

  • 防止反射攻击:即使构造函数是私有的,也可以通过反射来调用构造函数创建多个实例。
  • 防止序列化创建多个实例:如果一个单例类实现了Serializable接口,那么它的序列化和反序列化可能会创建多个实例。可以通过提供readResolve方法来解决这个问题。

结论:

单例模式是一个非常有用的设计模式,但实现它需要注意多线程安全、反射、序列化等问题。在Java中,使用枚举实现单例是最简单、安全的方法。但无论选择哪种方法,都要确保满足单例的基本原则和要求。

标签:Singleton,Java,private,instance,详解,static,单例,public
From: https://blog.51cto.com/u_16170893/7044356

相关文章

  • 初学者Java应该学jdk什么版本?
    Java的多个版本在历史上都有其重要性,但对于初学者而言,选择合适的版本来学习非常关键。以下是对于初学者来说选择JDK版本的一些建议:1.考虑最新稳定版本最新版本:目前JDK17是最新的长期支持版本(LTS)。选择最新的LTS版本作为学习起点是个不错的选择,因为它结合了稳定性和较新的特性。2.......
  • Vue进阶(幺肆捌):Vuex 辅助函数详解
    (文章目录)一、前言一般情况下,如果需要访问vuex.store中state存放的数据,需要使用this.$store.state.属性名方式。显然,采取这样的数据访问方式,代码略显繁杂,辅助函数为了解决繁杂行问题应运而生。二、辅助函数通过辅助函数mapGetters、mapState、mapActions、mapMutations,把vuex.......
  • javaScript操作符
    1运算符运算符(operator)也被称为操作符,是用于实现赋值、比较和执行算数运算等功能的符号。JavaScript中常用的运算有:算数运算符递增和递减运算符比较运算符逻运算符赋值运算符2算术运算符2.1算术运算符的概述概念:算术运算符使用的符号,用于执行两个变量或值的算术运算。运算符描......
  • java中int默认是0,Integer默认是null
    在Java中,int是一种原始数据类型,它默认的初始值是0。原始数据类型在声明时会自动初始化为其默认值。而Integer是Java中的一个包装类,它用于将int封装为对象。Integer对象的默认值是null,即未经初始化时,Integer对象的值为null。需要注意的是,当我们使用Integer对象时,如果没有明确地给......
  • centos7中用docker部署java项目调用mvs海康相机拍照踩坑
    一、海康机器人官网下载MVSV2.1.2(Linux)二、解压后将tar.gz包传入centos7中三、解压并安装MVS 安装 四、执行MVS,并查看环境变量是否正确安装后会新增/opt/MVS目录,进入/opt/MVS/bin目录执行./MVS 执行完成后查看是否已经自动添加环境变量,执行vi/etc/profile,会自动......
  • 谷粒商城报错:java.lang.IllegalStateException: Failed to load property source from
    遇到这种问题如果检查了配置文件没有出错可以尝试打开target文件,去找配置文件,查看是否为空或者中文乱码,一般情况下删除中文注释就可以,因为这个文件的编码格式是GBK,项目的编码格式是UTF-8,注释乱码,导致编译失败。还有另一种做法就是更改编码。......
  • 【JAVA】 将csv格式文件转换为pdf格式文件
    publicvoidcsvtopdf(){StringcsvFilePath="E:/tmp/output.csv";StringpdfFilePath="E:/tmp/outputPdf.pdf";try{Documentdocument=newDocument();PdfWriter.getInstance(document,newFileOutputStr......
  • 推荐一个java开源Saas进销存系统
    推荐一款Java开源的Saas进销存系统:管店云开源进销存系统管店云开源进销存系统是一款采用Java语言开发的Saas进销存系统,基于优秀的国产框架Jfinal框架和MySQL数据库。该系统包括采购、销售、库存、财务等模块,可以满足企业对进销存管理的所有需求。相比于其他同类系统,管店云开源Saas......
  • 一文详解自然语言处理两大任务与代码实战:NLU与NLG
    自然语言处理(NLP)涵盖了从基础理论到实际应用的广泛领域,本文深入探讨了NLP的关键概念,包括词向量、文本预处理、自然语言理解与生成、统计与规则驱动方法等,为读者提供了全面而深入的视角。作者TechLead,拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦......
  • AES加密 flutter java后台用的 AES/CBC/PKCS5Padding
     可测试AES是否正确的网址https://www.toolhelper.cn/SymmetricEncryption/AES java后台代码如下publicstaticStringencrypt(StringclearText,Stringkey,Stringiv){byte[]result=null;try{byte[]key_bytes=toByte(MD5Util......