单例模式的七种实现

Java 实现单例模式的七种写法 单例模式(Singleton Pattern) 是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。 阅读详情

转载出处:http://cantellow.javaeye.com/blog/838473

第一种(懒汉,线程不安全):

 1  public   class  Singleton {  
 2       private   static  Singleton instance;  
 3      private Singleton (){}   
 4       public   static  Singleton getInstance() {  
 5       if  (instance  ==   null ) {  
 6          instance  =   new  Singleton();  
 7      }  
 8       return  instance;  
 9      }  
10  }  
11 

这种写法lazy loading很明显,但是致命的是在多线程不能正常工作。

第二种(懒汉,线程安全):

 1  public   class  Singleton {  
 2       private   static  Singleton instance;  
 3      private Singleton (){}
 4       public   static   synchronized  Singleton getInstance() {  
 5       if  (instance  ==   null ) {  
 6          instance  =   new  Singleton();  
 7      }  
 8       return  instance;  
 9      }  
10  }  
11 

这种写法能够在多线程中很好的工作,而且看起来它也具备很好的lazy loading,但是,遗憾的是,效率很低,99%情况下不需要同步。

第三种(饿汉):

1  public   class  Singleton {  
2       private   static  Singleton instance  =   new  Singleton();  
3      private Singleton (){}
4       public   static  Singleton getInstance() {  
5       return  instance;  
6      }  
7  }  
8 

这种方式基于classloder机制避免了多线程的同步问题,不过,instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。

第四种(饿汉,变种):

 1  public   class  Singleton {  
 2       private  Singleton instance  =   null ;  
 3       static  {  
 4      instance  =   new  Singleton();  
 5      }  
 6      private Singleton (){}
 7       public   static  Singleton getInstance() {  
 8       return   this .instance;  
 9      }  
10  }  
11 

表面上看起来差别挺大,其实更第三种方式差不多,都是在类初始化即实例化instance。

第五种(静态内部类):

 1  public   class  Singleton {  
 2       private   static   class  SingletonHolder {  
 3       private   static   final  Singleton INSTANCE  =   new  Singleton();  
 4      }  
 5      private Singleton (){}
 6       public   static   final  Singleton getInstance() {  
 7           return  SingletonHolder.INSTANCE;  
 8      }  
 9  }  
10 

 

这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,它跟第三种和第四种方式不同的是(很细微的差别):第三种和第四种方式是只要Singleton类被装载了,那么instance就会被实例化(没有达到lazy loading效果),而这种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。想象一下,如果实例化instance很消耗资源,我想让他延迟加载,另外一方面,我不希望在Singleton类加载时就实例化,因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化instance显然是不合适的。这个时候,这种方式相比第三和第四种方式就显得很合理。

第六种(枚举):

1  public   enum  Singleton {  
2      INSTANCE;  
3       public   void  whateverMethod() {  
4      }  
5  }  
6 

这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒啊,不过,个人认为由于1.5中才加入enum特性,用这种方式写不免让人感觉生疏,在实际工作中,我也很少看见有人这么写过。
 

第七种(双重校验锁):

 1  public   class  Singleton {  
 2       private   volatile   static  Singleton singleton;  
 3      private Singleton (){}   
 4       public   static  Singleton getSingleton() {  
 5       if  (singleton  ==   null ) {  
 6           synchronized  (Singleton. class ) {  
 7           if  (singleton  ==   null ) {  
 8              singleton  =   new  Singleton();  
 9          }  
10          }  
11      }  
12       return  singleton;  
13      }  
14  }  
15 

这个是第二种方式的升级版,俗称双重检查锁定,详细介绍请查看:http://www.ibm.com/developerworks/cn/java/j-dcl.html

在JDK1.5之后,双重检查锁定才能够正常达到单例效果。

总结

有两个问题需要注意:

     1、如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,例如一些servlet容器对每个servlet使用完全不同的类  装载器,这样的话如果有两个servlet访问一个单例类,它们就都会有各自的实例。

     2、如果Singleton实现了java.io.Serializable接口,那么这个类的实例就可能被序列化和复原。不管怎样,如果你序列化一个单例类的对象,接下来复原多个那个对象,那你就会有多个单例类的实例。

对第一个问题修复的办法是:

 1  private   static  Class getClass(String classname)      
 2                                            throws  ClassNotFoundException {     
 3        ClassLoader classLoader  =  Thread.currentThread().getContextClassLoader();     
 4        
 5         if (classLoader  ==   null )     
 6           classLoader  =  Singleton. class .getClassLoader();     
 7        
 8         return  (classLoader.loadClass(classname));     
 9     }     
10  }  
11 

 

 对第二个问题修复的办法是: 

 1  public   class  Singleton  implements  java.io.Serializable {     
 2      public   static  Singleton INSTANCE  =   new  Singleton();     
 3        
 4      protected  Singleton() {     
 5          
 6     }     
 7      private  Object readResolve() {     
 8               return  INSTANCE;     
 9        }    
10  }   
11 

对我来说,我比较喜欢第三种和第五种方式,简单易懂,而且在JVM层实现了线程安全(如果不是多个类加载器环境),一般的情况下,我会使用第三种方式,只有在要明确实现lazy loading效果时才会使用第五种方式,另外,如果涉及到反序列化创建对象时我会试着使用枚举的方式来实现单例,不过,我一直会保证我的程序是线程安全的,而且我永远不会使用第一种和第二种方式,如果有其他特殊的需求,我可能会使用第七种方式,毕竟,JDK1.5已经没有双重检查锁定的问题了。

========================================================================

 superheizai同学总结的很到位:

 

不过一般来说,第一种不算单例,第四种和第三种就是一种,如果算的话,第五种也可以分开写了。所以说,一般单例都是五种写法。懒汉,恶汉,双重校验锁,枚举和静态内部类。

我很高兴有这样的读者,一起共勉。

(详细教程)opencv+pycharm+笔记本摄像头 做一个人脸识别 文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 一、安装opencv-python 这里推荐使用pycharm直接安装opencv-python 打开文件——设置——python解释器——点击+号 搜索opencv-python,点击安装包,等待片刻即可安装好 检查是否安装好,新建一个项目输入以下代码,若无报错则安装好 import cv2 二、准备分类器 咱们使用opencv官方提供的分类器,包括面部识别,侧... 阅读详情

相关推荐

金融科技创新中人工智能的应用:8篇优质论文精选(含2023)

随着科技的飞速发展,金融领域正经历着前所未有的变革。在这个过程中,人工智能技术发挥着越来越重要的作用。为了深入探讨金融人工智能的研究和应用,享享特地整理了几篇金融人工智能方面的论文,大家可以看一下金融人工智能方向最新的研究成果!面向金融领域的大型语言模型本文介绍了BloombergGPT,一个基于广泛金融数据训练的500亿参数模型。基于彭博(Bloomberg)广泛数据来源,建立了一个基于彭博数据的3630亿令牌数据集,并结合了额外3450亿通用数据令牌。

2401_82426425的博客 3212

7种单例模式实现

目录单例模式介绍0. 静态类使用1. 懒汉模式(线程不安全)2. 懒汉模式(线程安全)3. 饿汉模式(线程安全)4. 使用类的内部类(线程安全) 推荐5. 双重锁校验(线程安全)6. CAS「AtomicReference」(线程安全)7. Effective Java作者推荐的枚举单例(线程安全)总结 单例模式可以说是整个设计中最简单的模式之一,而且这种方式即使在没有看设计模式相关资料也会常用在编码开发中。因为在编程开发中经常会遇到这样一种场景,那就是需要保证一个类只有一个实例哪怕多线程同时访问,并需要提

qq_63815371的博客 737

手把手教你用QEMU模拟AST2600-EVB开发板:OpenBMC环境搭建全流程

本文提供了一份详尽的实战指南,手把手教你使用QEMU模拟器搭建AST2600-EVB开发板的OpenBMC环境。内容涵盖从工具链准备、系统镜像获取(官方与自编译),到QEMU启动命令解析、网络配置(用户与桥接模式),以及通过SSH、WebUI和Redfish API访问服务的全流程,帮助开发者在个人电脑上快速构建安全、可复现的嵌入式开发与测试沙盒。

play7的博客 1132

设计模式——单例模式(七种实现方法)

1. 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 单例模式结构图: 单例模式有多种写法各有利弊,现在我们来看看各种模式写法。 2. 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return insta

程序员博客 508

Tribon Vitesse开发教程(一)

Tribon Vitesse简介 Tribon Vitesse是Tribon提供给Python编程语言的编程接口,它是一系列的API。使用Python的语法调用这些API,结合Python语言自身的语法生成的程序叫做Vitesse程序。Vitesse是法语“速度”的意思,读作“为戴斯”。使用Tribon Vitesse可以直接访问Tribon产品信息模型和使用Tribon应用程序的功能,以控制设计

forevermemory的专栏 2593

VMware桥接模式实战:用手机热点给Linux虚拟机共享网络(附WiFi适配技巧)

本文详细介绍了在移动办公场景下,如何为VMware中的Linux虚拟机配置桥接模式,以通过手机热点共享网络。文章深入解析了桥接模式在无线环境下的工作原理,提供了从主机端准备、VMware设置到Linux虚拟机内部配置的完整实战步骤,并针对手机热点的特殊性,分享了MTU优化、DNS配置及常见网络问题的诊断与解决方案,帮助用户实现稳定高效的移动虚拟化办公。

2y3u4i5o6p的博客 1196

设计模式——单例模式的七种实现方法

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 单例模式结构图: 单例模式有多种写法各有利弊,实际项目中用的也很多,面试中也有很多几乎是标配,现在我们来看看各种模式写法。 1. 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){ } public static Single

胡八一的博客 260

MTK平台 MT6789 烧录 efuse 3.0 Configuration SOP

=====================生成cert1和cert2 key===============================================生成efuse key相关文件===========================================签名DA==========================================================正常编译。=====================Security3.0 的SOP 说明。

a785722173的博客 2329

设计模式:单例模式(7种实现方式)

单例模式,顾名思义就是只有一个实例,并且它自己负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 1、饿汉式: /** * @Auther: yjntue * @Date: 2020/3/4 19:48 * @Description: * 饿汉式 若一个类的成员都是比较重的资源,这种方式不合适 * 不允许被继承 */ public ...

yjntue的专栏 322

SAP_MM模块库存概览俄罗斯报表简介

本文介绍了SAP MM模块中"库存概览俄罗斯报表"的功能与应用。该报表主要用于查看物料在不同库存地点和类型的库存情况,并满足俄罗斯当地法规要求。文章解释了"俄罗斯报表"可能指代本地化合规库存报表或客户自定义报表,详细说明了事务代码J3RFLVMOBVEDH的操作步骤,包括公司代码、物料编码、日期范围等查询条件,并解释了报表中各字段含义如期初期末库存数量与价值。最后强调在物料分类账处理完成后使用该报表可获得实际库存价值,为SAP用户提供了实用的库存管理参考。

我小时候很黑的博客 1088

zemax---光学设计基础概念篇(持续更新中)

光学设计相关知识概念

u011699626的博客 1145

单例模式的七种实现方式及优缺点

单例模式什么是单例模式为什么需要单例模式单例模式的基本构造常见的七种单例模式的写法饿汉式单例模式经典的单例模式(线程不安全)懒汉式单例模式(线程安全)双重检查实现懒汉式单例模式另一种懒汉式单例模式静态内部类实现单例模式枚举实现单例模式通过反射破坏单例模式单例模式的优点单例模式的缺点 什么是单例模式 简单来说,就是用来创建独一无二的,只有一个实例对象,是一种最简单的设计模式。 特点: 1.一个类只能...

weixin_43420278的博客 2481

使用VNA(Vector Network Analyzer)对S参数进行去嵌(二)

无论是使用 EM 仿真工具创建的简化模型(如一段理想传输线)还是复杂模型用于测试夹具,现在都需要使用该 S 参数模型执行去嵌入过程。

小孟同学的博客 6109

七种方法实现单例模式

笔记来源:尚硅谷 目录一、单例模式的介绍二、饿汉式应用实例饿汉式(静态常量)饿汉式(静态代码块)三、懒汉式应用实例懒汉式(线程不安全,不推荐使用)懒汉式(线程安全,同步方法,也不推荐)四、双重检查(推荐使用)五、静态内部类(推荐使用)六、枚举(推荐使用) 一、单例模式的介绍 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。 比如Hibernate的SessionFactory,它充当数据存储源的代理,并负责创

weixin_43762820的博客 903

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

单例模式及其七种代码实现

单例模式 一、含义:保证一个类只有一个实例,并提供一个访问它的全局访问点。 二、实现思路 (1)私有化构造方法 (2)类内部构建实例 (3)提供一个共有的静态方法,返回对象实例 三、七种实现代码 (1)饿汉式(静态常量) // 优点:类装载的时候就实例化了,避免了线程同步问题 // 缺点:如果没有用到就会造成内存浪费 // 结论:在开发中可以使用,但可能会造成内存浪费 public class SingletonHungry{ //1、私有化构造器 private SingletonHung

xvhaoxiong的博客 1605

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Java单例模式的七种实现方式

推荐实现:枚举:最简洁、安全,适合大多数场景。静态内部类:延迟加载且线程安全,兼容旧JDK。避免使用:非线程安全的懒汉式(多线程环境)。同步方法/代码块(性能敏感场景)。扩展场景:ThreadLocal:需每个线程独立实例时使用。容器式单例:管理多个单例对象时适用。通过合理选择实现方式,可平衡性能、线程安全与代码简洁性。

DKPT的博客 1082

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深入解析单例模式的七种实现

https://www.jianshu.com/p/4014472ac79d

Hningning的博客 170

单例模式以及七种实现方式

原文链接:https://www.jianshu.com/p/ad86f107425c

代码君的博客 819

面试必问:你真的了解单例模式吗?:单例模式七种经典实现,从原理到实战

单例模式深度解析 本文系统介绍了单例模式的七种经典实现方式,从基础到高级,全面剖析其核心原理与适用场景。

1019

单例模式的七种不同的实现

第一种(懒汉,线程不安全):   Java代码   public class Singleton {      private static Singleton instance;      private Singleton (){}        public static Singleton getInstance() {      if (instance == nu

jeffasd的专栏 545

单例模式的七种实现方式

参考:http://cantellow.iteye.com/blog/838473

pymqq的专栏 593

Java单例模式七种实现

一、Java单例模式实现可分为七种比较经典的模式,从实现方式可分为懒汉模式,单例模式的实现有线程安全和线程不安全,饿汉模式,枚举模式,饿汉模式是在类加载的时候创建单例对象,既能保证线程安全。 1、懒汉模式,线程不安全,第一次使用的时候创建。 public class SingletonExample1 { // 私有构造函数 private SingletonExample1() { } // 单例对象 private static SingletonEx

yf_yf_yf_yf的博客 198

单例模式(七种实现方法)

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 单例模式结构图: 单例模式有多种写法各有利弊,现在我们来看看各种模式写法。 1. 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton (...

weixin_33759269的博客 149

Java单例模式的七种实现方式与测试七种单例模式并输出对应的结果

【代码】Java单例模式的七种实现方式与测试七种单例模式并输出对应的结果。

DKPT的博客 588
上一篇: Eclipse中web项目必须修改server配置才可以部署到Tomcat目录的webapps下
方方
博客等级 码龄15年 6粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值