- 浏览: 107870 次
- 性别:
- 来自: 惠州
文章分类
最新评论
-
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 1141myeclipse9.0运行速度比之前的版本提高了少,用起 ... -
final finally finallize 区别
2012-04-27 17:28 1015final定义的变量的值不能改变,定义的方法不能被覆盖, ... -
23种设计模式的形象比喻
2012-04-21 14:42 9681、ABSTRACT FACTORY— ... -
MAP,SET,LIST,等JAVA中集合解析(了解)
2012-04-19 09:46 962在JAVA的util包中有两个所有集合的父接口Collecti ... -
快速排序算法
2012-04-13 22:01 999快速排序是目前使用可 ... -
Java 排序算法
2012-04-13 21:38 1208package Sort; /** * 排 ... -
实例分析MySQL JDBC驱动
2012-04-12 15:19 1147http://developer.51cto.com/art/ ... -
java JDBC连接不同的数据库写法
2012-04-12 15:16 912一、DB2 Class.forName(& ... -
java枚举类型
2012-04-05 15:13 732public class TestEnum { /* ... -
struts2输入校验
2012-03-29 08:47 0一. 手动输入完成校验 1.普通的处理方式:只需要在actio ... -
MyEclipse6.5的速度性能优化大提速
2012-03-11 13:12 991MyEclipse是Eclipse的插件,也是一款功能强 ... -
JUnit, HttpUnit, Castus, JMeter之间的区别
2011-12-20 16:24 1769·单元测试:JUnit (http://www.junit.o ... -
org.hibernate.exception.DataException: Could not execute JDBC batch update
2011-12-06 16:19 2887做项目时忘记写下这句了request.setCharacter ... -
java.lang.NoClassDefFoundError: Could not initialize class util.HibernateUtil
2011-12-05 23:04 21423java.lang.NoClassDefFoundErr ... -
Hibernate3.1插入中文乱码解决办法
2011-12-04 19:44 8231、修改my.ini,修改default-charac ... -
Exception in thread "main" java.lang.NoClassDefFoundError: javax/persistence/Cac
2011-12-04 19:14 922javax.persistence.Cacheable 是 ... -
抽象类和接口之间的区别
2011-11-13 07:30 828抽象类和接口之间的区别: 一个类可以实现任意多个接口 ... -
HtmlParser初步研究
2011-11-12 19:33 821HtmlParser初步研究 by l ... -
JAVA中clone机制
2011-11-12 19:32 760http://onlylove.iteye.com/blog/ ... -
JAVA中native方法
2011-11-12 19:31 808Java不是完美的,Java的不足除了体现在运行速度上要比 ...
相关推荐
本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)...进阶篇有反射、泛型、注解、网络编程、多线程、序列化、数据库、Servlet、JSP、XML解析、单例模式与枚举。本专栏主要为Java入门者提供实验参考。
通常单例模式在Java语言中,有两种构建方式: 懒汉式—线程不安全:最基础的实现方式,线程上下文单例,不需要共享给所有线程,也不需要加synchronize之类的锁,以提高性能。...java中枚举类本身也是一种单例模式
单例模式,是一种常用的软件设计模式。通过单例模式可以保证系统中,**应用该模式的这个类只有一个实例**。即一个类只有一个对象实例。 #### 单例设计模式实现步骤 1. 将构造方法私有化,使其不能在类的外部通过new...
一个单例模式的晋级过程(饿汉-懒汉-DCL-IoDH-枚举) ...单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一
目录单例模式懒汉式单例模式未初始化问题解决Double Check 双重检查方案一:不让第二步和第三步重排序-DoubleCheck方案二:基于类初始化-静态内部类饿汉式饿汉式与懒汉式最大区别序列化破坏单例模式原理枚举单例基于...
本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)...进阶篇有反射、泛型、注解、网络编程、多线程、序列化、数据库、Servlet、JSP、XML解析、单例模式与枚举。本专栏主要为Java入门者提供实验参考。
单例设计模式:★★★★★ 156 工厂模式★★★★★ 159 抽象工厂模式★★★★★ 163 建造者模式 170 原型模式 177 适配器模式 182 桥接模式 188 过滤器模式 192 组合模式 193 装饰器模式★★★★★ 196 外观模式 201...
32 单例模式 47 32.1 饿汉模式 47 32.2 懒汉模式 47 33 接口(interface) 48 33.1 如何创建一个接口。 48 33.2 如何使用接口 48 33.3 如何使用类实现一个接口 49 33.4 接口的细节 49 34 接口的应用(面向对象分析)...
2. Java基础语法、类型转换、运算符、Scanner 3. 分支结构、循环结构、随机数 4. 数组详解、Debug工具使用 5. 方法详解 6. 编程思维案例 7. 面向对象基础 8. 常用API 9. 综合项目实战 Java加强篇包括: 1. static、...
day02-抽象类、接口、代码块,final、单例、枚举 day03-多态、包、权限修饰符、内部类,Object类,Date类 day04-常用API、正则表达式,泛型、Collection集合API day05-迭代器,数据结构,List,Set ,TreeSet集合,...
实例31 单例模式(Singleton) 75 实例33 开车(简单工厂模式) 77 实例33 旅游(工厂方法模式) 79 实例34 花园布局(抽象工厂模式) 80 实例35 几何图形(适配器模式) 82 第6章 字符串 85 实例36 获取字符...
8 Singleton单例模式 2. 9 Factory工厂模式 2. 10 Adapter适配器模式 第3章 数字 3. 1 数字与数字封装类 3. 2 格式化数字 3. 3 数字的舍入 3. 4 转换数字的进制 3. 5 生成随机数 ...
枚举单例(线程安全,调用效率高,不能延时加载) : 简单工厂模式:用来生产同一等级结构中的任意产品(对已有产品新增功能,需要修改源代码)虽然能通过工厂来创建对象,但是违反了开闭原则。一旦增加功能需要在...
Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型封装类 booleanBoolean charCharacter byte...
单例模式 & 多例模式 代理模式 策略模式 原型模式 工厂模式 委托 其他 Spring5 IOC容器设计原理及高级特性 AOP设计原理 FactoryBean和BeanFactory Spring事务处理机制 Spring JDBC Spring MVC九大组件 手动实现...
Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型 封装类 boolean Boolean char Character ...
java逻辑思维笔试题Effective Java - 第三版笔记 章节索引 ...枚举类型提供了这种保证 (PRO) 静态方法可以返回其返回类型的任何子类型的对象,与构造函数不同 这会导致 API 紧凑 适合基于接口的框架(条目
1.5.3 序列化单例和类型安全的枚举 1.5.4 版本管理 1.5.5 为克隆使用序列化 1.6 文件管理 1.7 新I/O 1.7.1 内存映射文件 1.7.2 缓冲区数据结构 1.7.3 文件加锁机制 1.8 正则表达式 第十二章 XML 2.1 XML概述 2.1.1 ...
通过单例模式获取到对象后。就是只有一个对象的类 方法全部都是非static修饰的,调用方式:对象名.方法名(...); 4. 工具类命名: XxxUtil、XxxUtils、XxxTool、XxxTools 3. jar 包 (掌握)...