单例的七种写法

一张图生成全套亚马逊Listing图与视频:AI流水线实操指南 跨境电商上架商品时,亚马逊规则要求提供多张商品图片和视频,而供应商通常只给一张基础图。理解Listing图片的底层逻辑——主图、场景图、尺寸图、特写图分别承担不同的转化任务,是解决图片数量不足的关键。借助AI出图和AI视频生成工具,配合基础平面设计能力,可以把单张原图拆解成完整素材资产:从透明PNG抠图、白底主图标准化,到多角度生成、场景合成、尺寸标注、卖点对比,再到15秒至60秒的分层视频脚本,形成一套可复制的生产流水线。这套方法适合跨境电商运营、产品设计和内容制作人员,能有效缩短新品上架周期,降低视觉物 阅读详情

http://www.360doc.com/content/14/0218/15/7669533_353537401.shtml

写的很全

个人喜欢内部静态类方式

双重加锁检查模式没有太多的优点。


原文如下:

转载出处: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同学总结的很到位:

 

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

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


【Java硬核知识:设计模式落地误区】单例模式的七种写法:从DCL到枚举的终极进化 摘要:单例模式作为 Java 设计模式中最为基础且常用的模式之一,其实现方式多样。本文深入探讨了单例模式的七种常见写法,从双检锁(DCL)到枚举单例的演变过程。着重分析了双检锁中 volatile 的必要性、静态内部类实现延迟加载的原理以及枚举单例防反射攻击的原理。通过详细的实操流程和完整代码示例,帮助开发者正确理解和运用单例模式,避免在实际开发中陷入设计模式落地的误区。 阅读详情

相关推荐

Win10系统内存占用异常飙升?三步排查法快速定位问题根源

本文针对Win10系统内存占用异常飙升问题,提供了一套三步排查法。首先利用任务管理器和资源监视器进行深度系统体检,定位隐形内存消耗者;其次通过干净启动和禁用非必要后台服务,揪出导致内存泄漏的第三方软件或驱动;最后进行终极深度清理,包括检查内存完整性、调整虚拟内存设置以及更新关键驱动程序,帮助用户快速恢复系统流畅运行。

weixin_29251567的博客 194

设计模式(二)单例模式的七种写法

面试的时候,问到许多年轻的Android开发他所会的设计模式是什么,基本上都会提到单例模式,但是对单例模式也是一知半解,在Android开发中我们经常会运用单例模式,所以我们还是要更了解单例模式才对。 **定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。**

Android进阶三部曲 - 刘望舒 7万+

大数据架构中的数据血缘追踪技术解析

数据血缘(Data Lineage)是指数据从源头到目标的完整流转路径,它记录了数据在整个生命周期中的变化过程。在大数据架构中,数据血缘追踪技术已经成为数据治理的核心组成部分。本文旨在全面解析数据血缘追踪的技术原理、实现方法和应用实践,帮助读者深入理解这一关键技术。本文将从基础概念入手,逐步深入到技术实现细节,最后探讨实际应用和未来趋势。数据血缘的核心概念和技术原理数据血缘的数学模型和算法实现实际项目案例和代码解析主流工具和解决方案比较未来发展方向和技术挑战。

架构师的AI之路,分享AI应用开发架构的学习与实践。 687

常见的七种单例模式写法

定义:保证一个类仅有一个实例,并给外部提供一个访问它的全局访问接口。饿汉式/** * 饿汉式(无法向单例对象的构造方法传参) */ public class Singleton { private static final Singleton instance=new Singleton(); private Singleton(){} public static S...

杨的博客 798

高通camera调试经验总结

修改AF对焦模式 adb shell setprop vendor.debug.camera.af.manual 2 //使能手动对焦 adb shell setprop vendor.debug.camera.af.manual 0 //使能自动对焦

weixin_43381364的博客 1万+

一种解决STM32多串口同时收发的方法

在做项目中,遇到了同时调用串口通信时程序崩溃的问题,在项目中,串口1用作调试串口,串口2用作MQTT通信串口,串口3用作下位机通信串口, 串口1重定向以后,用库函数自带的printf函数打印字符串 串口2使用自己写的u2_printf函数,即va_list这套变参宏定义后使用vsprintf函数打印字符串 串口3刚开始使用串口2一样的打印方式,程序在调试调用到串口3打印函数时直接崩溃,后续将串口3改用dma转存输出,仍然无法正常调用 多次研究以后,采用三个串口都使用重定向后的库函数自带的printf

Zxp0605的博客 8796

单例模式的七种写法以及注意事项

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

zhou的专栏 3348

RTX 5090配Ubuntu 24.04踩坑记:手把手搞定OpenVLA-OFT环境(附版本避坑清单)

本文详细记录了在RTX 5090显卡和Ubuntu 24.04系统上部署OpenVLA-OFT环境的完整过程,包括驱动安装、CUDA配置、PyTorch版本选择等关键步骤。提供了经过验证的版本组合清单和常见错误解决方案,帮助开发者高效搭建AI开发环境。

weixin_30342209的博客 465

史上最全的七种单例写法——单例设计模式

附Java/C/C++/机器学习/算法与数据结构/前端/安卓/Python/程序员必读书籍书单大全: 书单导航页(点击右侧 极客侠栈 即可打开个人博客):极客侠栈 ①【Java】学习之路吐血整理技术书从入门到进阶最全50+本(珍藏版) ②【算法数据结构+acm】从入门到进阶吐血整理书单50+本(珍藏版) ③【数据库】从入门到进阶必读18本技术书籍网盘吐血整理网盘(珍藏版) ④【Web前端】从HT...

黑技的博客 545

C++碰撞检测库FCL安装(MinGW,CMake)

FCL碰撞检测库、libccd\Eigen库编译配置,全流程问题记录

weixin_45650767的博客 4673

SLAM 轨迹评估工具——EVO安装、使用介绍

evo是一款用于视觉里程计和SLAM问题的轨迹评估工具. 核心功能是能够绘制相机的轨迹, 或评估轨迹与真值之间的误差. 支持多种数据集的轨迹格式(TUM、KITTI、EuRoC MAV、ROS的bag), 同时支持这些数据格式之间的相互转换,本文轨迹展示以tum数据格式为例。

u010196944的博客 1万+

Java单例的七种写法

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

潘建南的博客 664

Python库CloudScraper详细使用(绕过 Cloudflare 的反机器人页面的 Python 模块)

CloudScraper是一个专门用于绕过Cloudflare反机器人保护的Python库,它基于requests库构建,能够处理Cloudflare的5秒盾、WAF和人机验证等防护机制。

数据知道的博客 1万+

java单例的七种写法

转自 http://www.blogjava.net/kenzhh/archive/2011/09/02/357824.html 第一种(懒汉,线程不安全): 1 public class Singleton { 2 private static Singleton instance;...

chuodun2183的博客 45

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

单例的七种写法以及一些排序算法

单例的七种写法以及一些排序算法

lf0814的博客 895

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

单例的七种写法(二)

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

zbyluxzing的专栏 394

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Android设计模式——单例的七种写法

单例模式的七种写法

linbots的博客 716

单例的七种写法 http://cantellow.iteye.com/blog/838473

例模式的七种写法 博客分类: 设计模式 多线程JVMServletIBMIDEA 转载请注明出处:http://cantellow.iteye.com/blog/838473 第一种(懒汉,线程不安全): Java代码 public class Singleton {      private static Singleton instan

u013305082的专栏 517

以下属于单例模式的优点的是_【干货】三分钟搞懂单例的七种写法(第八点你肯定没有听说过)...

前言 单例模式(Singleton Pattern)是 Java 23种设计模式中最简单的设计模式之一,但是也是面试中出现最频繁的设计模式之一,常见实现方法有:"饿汉式"、"懒汉式",但实际上,它总共有7种写法,要搞懂单例模式,首先要知道它有什么特点,它的特点如下:一个类只能有一个实例对象类的构造方法是private修饰类需要提供获取唯一实例的方法(一): 饿汉式特点: 可以理解成已经饿到极致...

weixin_34449682的博客 98

java例7_Java中单例七种写法(懒汉、恶汉、静态内部类、双重检验锁、枚举)

/**** 懒汉模式 1* 可以延迟加载,但线程不安全。* @author admin**/public class TestSinleton1 {private static TestSinleton1 sinleton;private TestSinleton1(){}public static TestSinleton1 getSinleton(){if(sinleton==null){...

weixin_39645041的博客 85

为什么我墙裂建议大家使用枚举来实现单例。

在所有的单例实现方式中,枚举是一种在代码写法上最简单的方式,之所以代码十分简洁,是因为Java给我们提供了enum关键字,我们便可以很方便的声明一个枚举类型,而不需要关心其初始化过程中的线程安全问题,因为枚举类在被虚拟机加载的时候会保证线程安全的被初始化。除此之外,在序列化方面,Java中有明确规定,枚举的序列化和反序列化是有特殊定制的。这就可以避免反序列化过程中由于反射而导致的单例被破坏问题。

xnxqwzy的博客 917

Java中单例七种写法(懒汉、恶汉、静态内部类、双重检验锁、枚举)

/*** * 懒汉模式 1 * 可以延迟加载,但线程不安全。 * @author admin * */ public class TestSinleton1 { private static TestSinleton1 sinleton; private TestSinleton1(){ } public static TestSinleton...

weixin_30411997的博客 86

单例模式与线程安全的攻防战(手撕七种写法!)

(血泪教训)在Spring框架中,默认Bean作用域就是单例的,但人家是通过容器保证的线程安全。自己手写单例时,一定要根据业务场景选择最合适的实现方式!(敲黑板)但缺点也很明显——就算不用这个实例,启动时也会占用内存。(性能警告)就像进自家厕所还要排队等钥匙,太憋屈了!但注意这已经不是传统意义上的单例了!(拍桌)今天咱们就掰开了揉碎了,把单例模式的七种写法挨个扒个底朝天!(危)当多个线程同时通过第一重检查时,可能会创建多个实例。下次面试官再让你手写单例,请优雅地甩出五种写法+原理分析,保证让TA眼前一亮!

devstream8的博客 429

Java单例模式的七种写法

Java单例模式的七种写法 第一种(懒汉,线程不安全): public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new...

tzllxya的博客 162
上一篇: tomcat线程池设置
下一篇: Zookeeper锁的简单实现
coder265
博客等级 码龄14年 5粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值