- 浏览: 110207 次
- 性别:
- 来自: 惠州
文章分类
最新评论
-
dw3799:
写个单列实现,只有阿里员工能写吗
枚举类型的单例模式(java) -
不再是小白:
错误太多!
枚举类型的单例模式(java) -
iljyh123:
1楼怎么猜到博主是阿里的员工
枚举类型的单例模式(java) -
limb99:
超赞。博主应该是阿里的员工吧
枚举类型的单例模式(java) -
yexinchen:
请问为什么呢?我也是这个问题!
java.lang.NoClassDefFoundError: Could not initialize class util.HibernateUtil
Inspired by Effective Java.
Singleton模式是在编程实践中应用最广泛的几种设计模式之一。以前知道的,实现单例的方法有两种(下面的A、B)。刚刚在读《Effective Java的时候》学到一种新的更好的方法(E):单元素的枚举类型。同时通过网上资料也知道了其他两种方法(C、D)。最后一种在Java中从1.5版本开始支持,其他语言在验证后说明。
A.饿汉式(类加载的时候就创建实例)。
代码如下:
public class MaYun {
public static final Mayun instance = new Mayun(); //静态的final的MaYun
private MaYun() {
//MaYun诞生要做的事情
}
public void splitAlipay() {
System.out.println(“Alipay是我的啦!看你丫Yahoo绿眉绿眼的望着。。。”);
}
}
Call:MaYun.instance.splitAlipay();
Feature:可以通过反射机制攻击;线程安全[多个类加载器除外]。
A+.饿汉变种[推荐]
public class MaYun {
private static Mayun instance = new Mayun();
private static getInstance() {
return instance;
}
private MaYun() {
//MaYun诞生要做的事情
}
public void splitAlipay() {
System.out.println(“Alipay是我的啦!看你丫Yahoo绿眉绿眼的望着。。。”);
}
}
A++.饿汉变种(类初始化的时候实例化instance):
public class MaYun {
private MaYun instance = null;
static {
instance = new MaYun();
}
private MaYun() {
//MaYun诞生要做的事情
}
public static MaYun getInstance() {
return this.instance;
}
public void splitAlipay() {
System.out.println(“Alipay是我的啦!看你丫Yahoo绿眉绿眼的望着。。。”);
}
}
B.懒汉式。
代码如下:
public class MaYun {
private static MaYun instance = null;
private MaYun() {
//MaYun诞生要做的事情
}
public static MaYun getInstance() {
if (instance == null) {
instance = new MaYun();
}
return instance;
}
public void splitAlipay() {
System.out.println(“Alipay是我的啦!看你丫Yahoo绿眉绿眼的望着。。。”);
}
}
Call:MaYun.getInstance().splitAlipay();
Feature:延时加载;线程不安全,多线程下不能正常工作;需要额外的工作(Serializable、transient、readResolve())来实现序列化。
B+.懒汉式变种。
public class MaYun {
private static MaYun instance = null;
private MaYun() {
//MaYun诞生要做的事情
}
public static synchronized MaYun getInstance() {
if (instance == null) {
instance = new MaYun();
}
return instance;
}
public void splitAlipay() {
System.out.println(“Alipay是我的啦!看你丫Yahoo绿眉绿眼的望着。。。”);
}
}
Feature:线程安全;效率比较低,因为需要线程同步的时候比较少。
C.静态内部类[推荐]。
代码如下:
public class MaYun {
private static class SigletonHolder {
private static final instance = new MaYun();
}
public static final getInstance() {
return SigletonHolder.instance;
}
private MaYun() {
//MaYun诞生要做的事情
}
public void splitAlipay() {
System.out.println(“Alipay是我的啦!看你丫Yahoo绿眉绿眼的望着。。。”);
}
Call:MaYun.getInstance().splitAlipay();
Feature:线程安全;延迟加载。
D.双重校验锁[不推荐]。
代码如下:
public class MaYun {
private volatile static MaYun instance;
private MaYun (){}
public static MaYun getInstance() {
if (instance == null) {
synchronized (MaYun.class) {
if (instance == null) {
instance = new MaYun();
}
}
}
return instance;
}
}
Feature:jdk1.5之后才能正常达到单例效果。
E.编写一个包含单个元素的枚举类型[极推荐]。
代码如下:
public enum MaYun {
himself; //定义一个枚举的元素,就代表MaYun的一个实例
private String anotherField;
MaYun() {
//MaYun诞生要做的事情
//这个方法也可以去掉。将构造时候需要做的事情放在instance赋值的时候:
/** himself = MaYun() {
* //MaYun诞生要做的事情
* }
**/
}
public void splitAlipay() {
System.out.println(“Alipay是我的啦!看你丫Yahoo绿眉绿眼的望着。。。”);
}
}
Call:MaYun.himself.splitAlipay();
Feature:从Java1.5开始支持;无偿提供序列化机制,绝对防止多次实例化,即使在面对复杂的序列化或者反射攻击的时候。
总之,五类:懒汉,恶汉,双重校验锁,静态内部类,枚举。
恶汉:因为加载类的时候就创建实例,所以线程安全(多个ClassLoader存在时例外)。缺点是不能延时加载。
懒汉:需要加锁才能实现多线程同步,但是效率会降低。优点是延时加载。
双重校验锁:麻烦,在当前Java内存模型中不一定都管用,某些平台和编译器甚至是错误的,因为instance = new MaYun()这种代码在不同编译器上的行为和实现方式不可预知。
静态内部类:延迟加载,减少内存开销。因为用到的时候才加载,避免了静态field在单例类加载时即进入到堆内存的permanent代而永远得不到回收的缺点(大多数垃圾回收算法是这样)。
枚举:很好,不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。但是失去了类的一些特性,没有延迟加载,用的人也太少了~~
以后多推广推广单元素枚举这种更好的单例实现方式。在项目中的代码开始修改实施
评论
发表评论
-
关于在MyEclipse9中导入ExtJs校验报错的处理办法
2012-05-01 14:23 1180myeclipse9.0运行速度比之前的版本提高了少,用起 ... -
final finally finallize 区别
2012-04-27 17:28 1058final定义的变量的值不能改变,定义的方法不能被覆盖, ... -
23种设计模式的形象比喻
2012-04-21 14:42 10301、ABSTRACT FACTORY— ... -
MAP,SET,LIST,等JAVA中集合解析(了解)
2012-04-19 09:46 993在JAVA的util包中有两个所有集合的父接口Collecti ... -
快速排序算法
2012-04-13 22:01 1039快速排序是目前使用可 ... -
Java 排序算法
2012-04-13 21:38 1242package Sort; /** * 排 ... -
实例分析MySQL JDBC驱动
2012-04-12 15:19 1199http://developer.51cto.com/art/ ... -
java JDBC连接不同的数据库写法
2012-04-12 15:16 947一、DB2 Class.forName(& ... -
java枚举类型
2012-04-05 15:13 762public class TestEnum { /* ... -
struts2输入校验
2012-03-29 08:47 0一. 手动输入完成校验 1.普通的处理方式:只需要在actio ... -
MyEclipse6.5的速度性能优化大提速
2012-03-11 13:12 1043MyEclipse是Eclipse的插件,也是一款功能强 ... -
JUnit, HttpUnit, Castus, JMeter之间的区别
2011-12-20 16:24 1835·单元测试:JUnit (http://www.junit.o ... -
org.hibernate.exception.DataException: Could not execute JDBC batch update
2011-12-06 16:19 2974做项目时忘记写下这句了request.setCharacter ... -
java.lang.NoClassDefFoundError: Could not initialize class util.HibernateUtil
2011-12-05 23:04 21531java.lang.NoClassDefFoundErr ... -
Hibernate3.1插入中文乱码解决办法
2011-12-04 19:44 8551、修改my.ini,修改default-charac ... -
Exception in thread "main" java.lang.NoClassDefFoundError: javax/persistence/Cac
2011-12-04 19:14 962javax.persistence.Cacheable 是 ... -
抽象类和接口之间的区别
2011-11-13 07:30 863抽象类和接口之间的区别: 一个类可以实现任意多个接口 ... -
HtmlParser初步研究
2011-11-12 19:33 851HtmlParser初步研究 by l ... -
JAVA中clone机制
2011-11-12 19:32 796http://onlylove.iteye.com/blog/ ... -
JAVA中native方法
2011-11-12 19:31 842Java不是完美的,Java的不足除了体现在运行速度上要比 ...
相关推荐
在Java等面向对象编程语言中,单例模式常用于管理共享资源,如数据库连接池、线程池或者配置文件等。结合工厂模式,可以进一步优化单例的创建过程,提高代码的可读性和可维护性。 单例模式的核心在于控制类的实例化...
此外,Java 5引入的枚举类型提供了一种简洁、线程安全且避免了反射攻击的单例实现方式: ```java public enum Singleton { INSTANCE; } ``` 单例模式虽然简单实用,但也存在一些缺点,如妨碍了继承、不支持多态...
JAVA 枚举单例模式是一种特殊的单例模式实现方式,它使用枚举类型来保证线程安全、防止序列化问题和反射攻击。下面我们将详细解释这个模式的实现原理和源码分析。 线程安全 在 Java 中,枚举类型的实例是在类加载...
在Java中实现单例模式有多种方法,包括懒汉式、饿汉式、双重检查锁定(DCL)、静态内部类以及枚举类型等。每种方式都有其优缺点,适用场景也不同。 1. **懒汉式**:延迟初始化,只有在第一次调用getInstance()方法...
为了解决这个问题,Java引入了枚举类型来实现单例模式,这是一种简洁且线程安全的方法。 枚举在Java中是特殊的类,由JVM自动管理,保证了线程安全。当枚举类被加载时,JVM会自动初始化所有的枚举实例,因此在多线程...
本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)...进阶篇有反射、泛型、注解、网络编程、多线程、序列化、数据库、Servlet、JSP、XML解析、单例模式与枚举。本专栏主要为Java入门者提供实验参考。
另外,还有基于枚举的单例模式,Java枚举类型是线程安全的,并且它们是天生的单例。枚举单例写法简洁,能够避免反射破坏单例的问题,并且它还能够防止反序列化重新创建新的实例。使用枚举实现单例模式时,Java虚拟...
除了以上三种经典的实现方式,Java 1.5之后引入了枚举类型,也提供了一种更简洁且线程安全的单例实现方式。通过定义一个枚举类,其中包含一个枚举常量,这个枚举常量即为单例实例。这种方式既保证了线程安全,又避免...
除了上述三种单例模式外,在Java中还可以使用枚举类型来实现单例模式。Java枚举的特性保证了枚举类型的单例性,因为枚举实例是类加载时创建的,且Java虚拟机保证不会创建重复的实例。 单例模式在很多情况下都是很...
使用枚举类型实现单例,既简单又线程安全,还能防止序列化破坏单例。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { // ... } } ``` 每种方法都有其优缺点。饿汉式虽然简单...
在Java中,实现单例模式有多种方法,包括懒汉式(线程不安全)、饿汉式(静态常量)、双检锁(DCL)和枚举单例。其中,双检锁和枚举单例是线程安全的,推荐在多线程环境下使用。 ```java // 双检锁/双重校验锁(DCL...
将单例定义为一个枚举类型,这样不仅能保证线程安全,还能防止反射攻击。枚举是JVM的固有特性,因此它的创建是线程安全的,并且不允许实例化多个枚举实例。 每种实现方式都有其优缺点,选择哪种方式取决于特定的...
Java中的23种设计模式中,单例模式是一种常见且实用的模式。 **单例模式的定义** 单例模式有三个关键特性: 1. 构造器私有化:不允许外部直接通过new关键字创建实例。 2. 持有一个自己类型的静态属性:存储唯一的...
在Java中实现单例模式有多种方法,包括懒汉式(线程不安全)、饿汉式(线程安全)、双重检查锁定(DCL,线程安全)以及枚举单例。确保单例模式正确实现的关键在于防止多线程环境下的多次实例化和序列化/反序列化时的...
5. **枚举类型**:Java枚举是天然的单例模式,既简单又安全。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { } } ``` 然而,单例模式并非总是完美的。它的缺点包括: - **测试...
使用枚举类型也可以实现单例模式,这是Java语言提供的原生态支持,不仅能自动支持序列化机制,而且绝对防止多次实例化。代码示例如下: ```java public enum Singleton { INSTANCE; public void someMethod()...
Java中的枚举类型是线程安全的,并且只会装载一次,设计者充分考虑到了线程安全问题,因此使用枚举实现单例模式是一种简洁而且高效的解决方案。 6. 容器式单例(Singleton Holder) 通过一个私有的静态内部类...
Java枚举类型是Java语言中一种特殊的类,用于定义固定的常量集合,它提供了一种安全、类型化的方式来表示一组有限的值。枚举在Java中被引入为一个完整的类型,不同于C++中的枚举,这使得Java枚举更加强大且易于使用...
在Java编程语言中,设计模式是一种经过验证的解决常见软件设计问题的最佳实践。单例模式是其中最常用的一种...在实际开发中,还可以使用枚举类型的单例,这是一种更简洁且线程安全的方式,避免了同步和双重检查的问题。
在 Java 中,单例模式的实现可以使用双重检查锁机制、静态内部类和枚举类型等方式。但是,这些方式都存在线程安全问题,例如在多线程环境下,多个线程可能会同时访问同一个实例,从而导致数据不一致和其他问题。 ...