- 浏览: 111413 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
yongliang567:
楼主,你对双重检查加锁这种单例实现方法的分析是对的,但是你既然 ...
关于单例(Singleton)模式实现方式的反思 -
xbl001529:
支持IE8吗?
[效果]JS折叠菜单
大家都知道单例模式,也知道实现的方法,最近看到几个网友推荐的文章,仔细思考了一下,发现我以前的想法是有问题的。
先看我一直使用的单例代码样例:
- /**
- * 一段我一直使用的单例实现的代码。
- *
- * @author 赵学庆,Java世纪网(java2000.net)
- *
- */
- public class Singleton {
- private static volatile Singleton instance;
- private Singleton() {
- }
- public static Singleton getInstance() {
-
if
(instance ==
null
) { // 1
-
synchronized
(Singleton.
class
) {
// 2
- if (instance == null ) // 3
- instance =
new
Singleton();
// 4
- }
- }
- return instance;
- }
- }
系统先判断是否已经初始化(1),
如果没有初始化则进入同步(2),
然后再次判断是否已经初始化(3),
如果还是没有则初始化一个(4).
系统考虑了多CPU问题,使用了 volatile
这个修饰符。 我自认这个代码没有任何问题,但是:??
一个文章里说到的奇怪的执行顺序引起了我的注意,我来说明一下2个线程的执行过程:
线程1这行到了(4),此时系统需要做的事情是给Singleton分配内容,然后进行初始化,可是对instance的赋值操作是在类初始化之前完成的。那没就会出现
线程2 此时拿到了CPU,此时判断instance 已经不再是null,于是他使用了这个已经分配了内存,但没有初始化完毕的类,然后造成运行结果异常。
这个问题我想还是很有可能的,毕竟我们无法保证JVM一定在类已经完全初始化完毕之后再赋值给instance。因为这样做,系统要额外分配一个变量用来
临时指向新分配的内存,完成所有的初始化之后再把内存指向instance。而正常的理解,肯定是不会额外的浪费这个变量的(希望我的猜测是错的,我宁可
我是错的)。
下面是我再次搜索并整理的更安全的初始化方法,大家参考看看:
第一种,使用静态初始化
- class Singleton {
- private static volatile Singleton instance = new Singleton();
- private Singleton() {
- }
- public static Singleton getInstance() {
- return instance;
- }
- }
- class Singleton {
- static class SingletonHolder {
- static volatile Singleton instance = new Singleton();
- }
- private Singleton() {
}
- public static Singleton getInstance() {
- return SingletonHolder.instance;
- }
- }
另外, 楼下网友提供的用临时变量的方法,你可以参考我的参考文章,里面讲述了理由。在一些编译器优化时,会把它优化掉,造成并不能达到我们要的结果。也就是编译器会认为你的那个临时变量是多余的。
期待牛人能给个更准确的说法。
参考文章:
1 解析 Java 类和对象的初始化过程
2 Java中的模式 --单态
3 The "Double-Checked Locking is Broken" Declaration
评论
1 楼
yongliang567
2011-02-12
楼主,你对双重检查加锁这种单例实现方法的分析是对的,但是你既然已经使用volatile来修饰instance变量,就排除了JVM对该变量的赋值进行优化的可能。volatile正是用来告诉编译器不进行你所说的这种优化。
发表评论
-
通过spring取得国际化文件
2012-03-23 16:18 1866/* * @(#) ScheduleController ... -
java 能否做成C/S架构的,同时他能否写程序调用IE框架
2008-10-20 14:21 1014据说现在java在C/S方面 有了很大进步,想着想写个程序。通 ... -
转载 java面向对象—抽象类、接口与多继承
2008-10-20 09:49 1238有时候,我们可能想要构造一个很抽象的父类对象,它可能仅仅代表一 ... -
JAVA命名和目录服务(JNDI)
2008-10-17 10:59 929在 J2EE 中, JNDI 的目的是用来查找 J2EE 服 ... -
java高级编程:基于JNDI的应用开发
2008-10-17 10:58 1093基于JNDI的应用开发 ... -
JAVA里protected属性和方法的完整测试
2008-10-13 13:53 1281先说几个protected的使用原则,后面再看对应的例子。 ... -
java中中文问题
2008-10-09 13:36 8561、如果一个数据库的编码是iso8859-1的,我在java代 ... -
如何使用Static的变量和方法
2008-09-26 14:25 851有时你希望定义一个类 ... -
dom4j读取xml(笔记)
2008-09-26 10:20 11149Java代码 SAXReader reader ... -
关于struts的几个注意的地方 第一章
2008-09-26 10:14 733J2EE开发中大量的专业缩略语很是让人迷惑,尤其是跟一些高手 ... -
关于struts的几个注意的地方
2008-09-26 09:59 727关于struts的几个注意的 ... -
Java Vector
2008-09-09 15:32 2841Vector 类可以实现可增长的对象数组。与数组一样,它包含 ... -
Linux 文件命令精通指南
2008-07-15 10:01 950为刚接触 Linux 文件命令的初学者提供的速成教程 ... -
Java 设计模式与建模专题
2008-07-09 15:32 971http://www.ibm.com/developerwor ... -
Java并发编程基础知识片段(一)
2008-06-27 16:45 955原创 Java并发编程基础知识片段(一)收藏 Java 5并发 ... -
关于junit实现过程详细介绍
2008-04-14 16:16 944测试分类:白箱测试、黑箱测试、单元测试、集成测试、功能测试…… ... -
循序渐进学习Junit
2008-04-14 16:15 1195用JUnit可以大量减少Java ... -
JUnit入门
2008-04-14 16:14 800JUnit是一个开源的java单元测试框架。在1997年,由 ... -
Java正则表达式入门
2008-03-18 17:38 875Java中正则表达式使用方法详解: http://tech.1 ... -
Java正则表达式入门
2008-03-18 13:56 849众所周知,在程序开发中,难免会遇到需要匹配、查找、替换、判断字 ...
相关推荐
深入浅出Singleton,详细掌握单例模式
java Singleton单例模式 java Singleton单例模式
在Java应用中,单例对象能保证在一个...3、有些像交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了,只有使用单例模式,才能保证核心交易服务器独立控制整个流程。 CSDN代码的详细解释。
此示例展示了Qml 的单例模式(类似全局对象,只生成一次实例,可全局使用) surfsky.cnblogs.com
设计模式C++学习之单例模式(Singleton)
简单的单例模式举例Singleton 分为恶汉式 懒汉式
单例模式是最简单的一种设计模式,确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例, 本资源提供了用java语言实现简单的单例模式,供初学者参考
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个...
单例模式的特点有三: 单例类只能有一个实例。 单例类必须自己创建自己的唯一实例。 单例类必须给所有其他对象提供这一实例。 Singleton模式包含的角色只有一个,就是Singleton。Singleton拥有一个私有构造函数,...
单例模式 Singleton 单例模式线程安全问题和拓展
单例模式(Singleton)的6种实现
Java代码单例实现方式:最全的单例实现方式汇总;
单例设计模式Singleton1
C++11实现线程安全的单例代码和测试代码,包含singleton.h,main.cpp,希望帮助到大家。
本文实例讲述了JS基于设计模式中的单例模式(Singleton)实现封装对数据增删改查功能。分享给大家供大家参考,具体如下: 单例模式 单例模式的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中...
singleton单例模式1
singleton 单例 java 详细介绍了单例模式的使用,很不错的单例模式的介绍
Singleton pattern单例模式应用
本文档,是利用C++来实现设计模式中的,单例模式,里面有内容说明和相关实例代码介绍