Java单例模式实现方法及对比分析

创始人
2024-12-26 06:31:20
0 次浏览
0 评论

什么叫单例模式,如何实现,有什么作用?

只有一个实例,最简单的单例模式可以使用static来实现。
例如,以下_Context变量使用单利模式。
下面的代码是,当外界想要调用_Context时,如果_Context已经实例化,则直接返回。
全局只有一个_Context,如publicclassEESGateway{privatestaticEESDatabaseDataContext_Context=null;//EESDatabasDataContexInstanceprivateconststringdatabaseName='EESDatabase';//DatabaseName//////ReturnEESDatabaseDataContextinstance.//////EESDatabaseDataContextinstancepublicstaticEESDatabaseDataContextDataContext(){if(_Context==null){lock(typeof(EESGateway)){//formatenewstringtostoretheconnectionStringStringconnectionString=ConfigurationManager.ConnectionStrings["EESDatabase"].ConnectionString;//createdataContextusingtheconnectionStringabove_Context=newEESDatabaseDataContext(connectionString);}}return_Context;}}

如何在java中实现singleton模式

Singleton模式是设计模式之一,其主要目的是确保一个类只有一个实例并提供一个全局访问点。
在Java中,有五种方法来实现单例模式:懒惰风格、饥饿风格、静态内部类、枚举和双重检查锁定。
懒人风格是应用最广泛的实现方法。
它在类中定义静态私有变量,并在类的内部方法中初始化实例。
第一次调用getInstance方法时,会创建并返回一个实例。
惰性风格实现如下:classLazySingleton{privatestaticLazySingletonsingleton;privateLazySingleton(){}publicstaticLazySingletongetInstance(){if(singleton==null){singleton=newLazySingleton();}returnsingleton;}}Hungry风格创建一个实例,当类已加载。
这种方法保证了线程安全,但可能会导致资源浪费,因为类实例在加载时就已经创建好了。
Hungry风格的实现如下:classHungrySingleton{privatestaticHungrySingletonsingleton=newHungrySingleton();privateHungrySingleton(){}publicstaticHungrySingletongetInstance(){returnsingleton;}}静态内部类的实现是只有当该内部类用于使用时才加载该内部类首次实现了延迟加载。
这种方式保证了线程安全,并且在加载类时不会创建实例。
静态内部类的实现如下:classInternalSingleton{privatestaticclassSingletonHolder{privatefinalstaticInternalSingletonINSTANCE=newInternalSingleton();}privateInternalSingleton(){}publicstaticInternalSingletongetInstance(){returnSingletonHolder.INSTANCE;}}enum实现通过enum类型保证实例的唯一性,并且可以防止通过反序列化重新创建新对象。
枚举的实现如下:enumEnumSingleton{INSTANCE;publicvoiddoSomeThing(){//dosomething}}最后一个方法是双重检查锁。
虽然在某些情况下可以提高性能,但是这种方法在当前的Java内存模型中是无效的。
双重检查锁的实现如下:classLockSingleton{privatevolatilestaticLockSingletonsingleton;privateLockSingleton(){}publicstaticLockSingletongetInstance(){if(singleton==null){synchronized(LockSingleton.class){if(singleton==null){singleton=newLockSingleton();}}返回单例;}}

如何在Java中实现单例模式?

单例模式的写法大致有五种,分别是懒人、恶人、静态内部类、枚举、双重检查锁。

1.惰性写入方法,常用的写入方法

classLazySingleton{privatestaticLazySingleton(){}publicstaticLazySingletongetInstance(){        if(singleton==null){singleton=newLazySingleton();                                                                                                                                                                p>2。
坏人类型方法的缺点是没有达到延迟加载的效果

classHungrySingleton{privatestaticHungrySsingletonsingleton=newHungrySingleton(){}publicstaticHungrySingletongetInstance(){returnsingleton}}

3、优点:静态变量INSTANCE不会被初始化,因为不主动使用,现在Lazyloading

类InternalSingleton{privatestaticclassSingletonHolder{privatefinalstaticInternalSingletonINSTANCE=newInternalSingleton(}privateInternalSingleton(){}publicstaticInternalSingletongetInstance(){returnSingletonHolder.INSTANCE}}

4枚举,好处:避免不仅是多线程的问题,而且还会阻止反序列化和恢复。
object

enumEnumSingleton{INSTANCE;doSomeThing(){}}

5双重检查锁在当前内存模型中无效

classLockSingleton{.privatevolatilestaticLocksingletonSingletonPrivateLocksingleton(){}//参见:http://www.ibm.com/developerworks/cn/java/j-dcl.htmlpublicstaticLocksingletonGeTinstance(){){){singleton=qu){singleton=newLockSingleton();                                返回单例;                                                                                                                                          

一种独特的单例模式写法,利用final语义实现

Singleton模式是Java编程中的经典主题。
它通常有静态内部类、枚举、Double-CheckedLocking等几种实现方法。
我最近注意到一种使用最终语义实现线程安全单例模式的新方法。
Final不仅象征着类、方法和属性的不变性,而且还隐含着重新排序读写的规则。
该规则的存在是为了解决Java内存模型中的一个关键缺陷:线程可以读取Final字段的值而不对其进行初始化。
通过改进Final的语义,JSR-133专家组引入了写入和读取重新排序规则,以确保当在构造函数中正确构造对象时,任何线程都可以看到其Final字段的初始化值,而无需使用同步操作。
Final字段写入规则确保Final字段在对象引用可用之前正确初始化,而常规字段则没有这样的保证。
相反,最后一个字段读取规则阻止处理器在读取最后一个字段之前重新排序对象引用读取该规则是通过在读取最后一个字段之前插入LoadLoad屏障来实现的。
讨论完最终语义及其规则后,让我们回到编写双重检查锁定的经典方法。
其中,Volatile关键字用于防止指令重新排序,并确保对象实例在初始化之前不可访问。
使用最终语义是否可以达到类似的效果?答:是的。
查看SEICERTwikiCMU,我们发现它没有使用双重检查编写易失性锁,而是使用最终语义。
这种写入方法本质上与使用易失性DCL相同。
不过,SEICERT指出,这种写入方法在某些Java虚拟机平台上可能无效,因为第一次和第三次读取并没有建立“之前发生”的关系。
这意味着编译器可以缓存或重新排序读取,结果为空值。
Java的“先发生”规则定义了操作之间的顺序关系,并确保程序正确执行。
在使用最终语义实现的单例模板中,如果对象引用的第一次读取为非空,则后续读取也必须为非空,除非存在编译器缓存或实现之间存在差异。
为了更好地理解Java中的并行编程,本文讨论了最终语义,但不建议在实际代码中使用。
我更喜欢使用Guava提供程序来实现单例模式。
这种方法简洁易懂,比自定义DCL或静态内部类和枚举实现更直观。
热门文章
1
SQL多表连接查询全解析:JOIN语句应... sql多表关联查询在执行SQL多表连接查询时,可以使用JOIN语句将多个表连接在...

2
Java中字符串类型详解:String与... 变量有字符类型,为什么没有字符串类型??基本类型:charshort、int、l...

3
JavaSE与JavaEE:从基础到企业... javase 和javaee的区别?JavaSE和JavaEE...

4
Java程序员面试必知:核心技术问答与技... java编程程序员技术面试常见面试?随着互联网的不断发展,Java开发已经成为很...

5
Java.exe与Javaw.exe:区... 程序中java和javaw有什么区别java和javaw的区别:两者都是Java...

6
深入解析:Java中的javax包及其与... JAVA导入时,什么是javax?awt是java1.0,swing是java2...

7
Excel高效指南:字符转数值的实用技巧 excel怎么将字符串转为数值1.您可以使用“VALUE”函数将字符串转换为数值...

8
Python编程错误解析与解决指南 Python错误大全本文记录了学习Python过程中遇到的一些警告错误以及纠正方...

9
Java高清视频处理技术解析:JAVAH... JAVAHDVIDEO:解析Java技术在高清视频处理中的创新应用!JAVAHD...

10
Java编程:深入解析抽象类与接口的五大... 抽象类和接口的区别在哪里?1其他方法接口方法默认是公共的,并非所有方法都可以在接...