- 浏览: 1148039 次
- 性别:
- 来自: 火星郊区
博客专栏
-
OSGi
浏览量:0
文章分类
- 全部博客 (695)
- 项目管理 (48)
- OSGi (122)
- java (79)
- Vaadin (5)
- RAP (47)
- mysql (40)
- Maven (22)
- SVN (8)
- 孔雀鱼 (10)
- hibernate (9)
- spring (10)
- css (3)
- 年审 (6)
- ant (1)
- jdbc (3)
- FusionCharts (2)
- struts (4)
- 决策分析 (2)
- 生活 (10)
- 架构设计 (5)
- 破解 (2)
- 狼文化 (4)
- JVM (14)
- J2EE (1)
- 应用服务器 (1)
- 我的链接 (5)
- 数学 (2)
- 报表 (1)
- 百科 (6)
- Flex (7)
- log4j (2)
- PHP (1)
- 系统 (2)
- Web前端 (7)
- linux (6)
- Office (1)
- 安全管理 (5)
- python (2)
- dom4j (1)
- 工作流 (3)
- 养生保健 (4)
- Eclipse (8)
- 监控开发 (1)
- 设计 (3)
- CAS (1)
- ZK (41)
- BluePrint (3)
- 工具 (1)
- SWT (7)
- google (2)
- NIO (1)
- 企业文化 (2)
- Windoes (0)
- RCP (7)
- JavaScript (10)
- UML (1)
- 产品经理 (2)
- Velocity (10)
- C (1)
- 单元测试 (1)
- 设计模式 (2)
- 系统分析师 (2)
- 架构 (4)
- 面试 (2)
- 代码走查 (1)
- MongoDB (1)
- 企业流程优化 (1)
- 模式 (1)
- EJB (1)
- Jetty (1)
- Git (13)
- IPV6 (1)
- JQuery (8)
- SSH (1)
- mybatis (10)
- SiteMesh (2)
- JSTL (1)
- veloctiy (1)
- Spring MVC (1)
- struts2 (3)
- Servlet (1)
- 权限管理 (1)
- Java Mina (1)
- java 系统信息 (6)
- OSGi 基础 (3)
- html (1)
- spring--security (6)
- HTML5 (1)
- java爬虫搜索 (1)
- mvc (3)
最新评论
-
Tom.X:
http://osgia.com/
将web容器置于OSGi框架下进行web应用的开发 -
chenyuguxing:
你好, 为什么我的bundle export到felix工程中 ...
在Apache Felix中运行bundle -
string2020:
<niceManifest>true</ni ...
Bundle Plugin for Maven -
jsonmong:
OSGI,是未来的主流,目前已相当成熟。应用OSGI比较好的, ...
基于OSGi的声明式服务 -
zyhui98:
貌似是翻译过来的,有很少人在linux上做开发吧
如何成为“10倍效率”开发者
已经有众多文章讨论 double-checked locking 模式在 Java 下面无法正常工作,这里先简要的总结一下。
根本原因在于 Java 的 memory model 允许所谓的 out-of-order write ,对于下面的 Java 代码,out-of-order write 可能导致灾难性的结果
public static Singleton getInstance() { if (instance == null) { synchronized(Singleton.class) { //1 if (instance == null) //2 instance = new Singleton(); //3 } } return instance; }
问题的起因在于语句 //3 ,JIT 所生成的汇编代码所作的事情并不是先生成一个 Singleton 对象,然后将其地址赋予 instance 。相反,它的做法是
1. 先申请一块空内存
2. 将其地址赋予 instance
3. 在 instance 所指的地址之上构建对象
下面的汇编代码提供了证明,说明这不只是一个脑筋急转弯,而是实际发生在 JIT 里面的。代码来自 Peter Haggar 的文章,我只是引用一下。
054D20B0 mov eax,[049388C8] ;load instance ref
054D20B5 test eax,eax ;test for null
054D20B7 jne 054D20D7
054D20B9 mov eax,14C0988h
054D20BE call 503EF8F0 ;allocate memory
054D20C3 mov [049388C8],eax ;store pointer in
;instance ref. instance
;non-null and ctor
;has not run
054D20C8 mov ecx,dword ptr [eax]
054D20CA mov dword ptr [ecx],1 ;inline ctor - inUse=true;
054D20D0 mov dword ptr [ecx+4],5 ;inline ctor - val=5;
054D20D7 mov ebx,dword ptr ds:[49388C8h]
054D20DD jmp 054D20B0
其中地址为 054D20BE 的代码正在分配内存,而接下来的一行将其赋予 instance ,这个时候 Singleton 的构造函数根本就还没有被调用。
那
么问题在哪里?如果线程调度发生在 instance 已经被赋予一个内存地址,而 Singleton
的构造函数还没有被调用的微妙时刻,那么另一个进入此函数的线程会发觉 instance 已经不为 null ,从而放心大胆的将 instance
返回并使用之。但是这个可怜的线程并不知道此时 instance 还没有被初始化呢!
症结在于:首先,构造一个对象不是原子操作,而是可以被打断的;第二,更重要的,Java 允许在初始化之前就把对象的地址写回,这就是所谓 out-of-order 。
那么,对于 C++ 呢?典型的 C++ double-checked locking 可能是这样的
static Singleton* getInstDC() { if(inst_ == 0) { boost::mutex::scoped_lock l(guard_); if(inst_ == 0) inst_ = new Singleton(); } return inst_; }
正
如 Java 的行为取决于 JIT 的处理方式,C++ 程序的行为要由编译器来决定。如果某个编译器的处理与 JIT 类似,那么 C++
程序员也只好对 double-checked locking 说再见。下面是 VC7.1 在 release 配置下生成的代码:
static Singleton* getInstDC()
{
00401110 mov eax,dword ptr fs:[00000000h]
00401116 push 0FFFFFFFFh
00401118 push offset __ehhandler$?getInstDC@Singleton@@SAPAV1@XZ (4095F8h)
0040111D push eax
if(inst_ == 0)
0040111E mov eax,dword ptr [Singleton::inst_ (40D000h)]
00401123 mov dword ptr fs:[0],esp
0040112A sub esp,8
0040112D test eax,eax
0040112F jne Singleton::getInstDC+6Eh (40117Eh)
{
boost::mutex::scoped_lock l(guard_);
00401131 mov ecx,offset Singleton::guard_ (40D004h)
00401136 mov dword ptr [esp],offset Singleton::guard_ (40D004h)
0040113D call boost::mutex::do_lock (401340h)
00401142 mov byte ptr [esp+4],1
if(inst_ == 0)
00401147 mov eax,dword ptr [Singleton::inst_ (40D000h)]
0040114C test eax,eax
0040114E mov dword ptr [esp+10h],0
00401156 jne Singleton::getInstDC+57h (401167h)
inst_ = new Singleton();
00401158 push 1
0040115A call operator new (4011A2h)
0040115F add esp,4
00401162 mov dword ptr [Singleton::inst_ (40D000h)],eax
}
00401167 mov ecx,offset Singleton::guard_ (40D004h)
0040116C mov dword ptr [esp+10h],0FFFFFFFFh
00401174 call boost::mutex::do_unlock (401360h)
return inst_;
00401179 mov eax,dword ptr [Singleton::inst_ (40D000h)]
}
0040117E mov ecx,dword ptr [esp+8]
00401182 mov dword ptr fs:[0],ecx
00401189 add esp,14h
0040118C ret
从标记为红色的那一句,我们看到了希望:对 inst_ 的赋值发生在 new 完成之后,这意味着至少在 VC7.1 中,我们尚且可以放心使用 double-checked locking ,尽管它未必具有可移植性。
一个替代方法:
class SingletonTest { private static SingletonTest instance; private SingletonTest { } private static class Instance//嵌套类只加载一次。 { static fianl SingletonTest Instance=new SingletonTest(); } public static SingletonTest() { return Instance.instance; } }
发表评论
-
一个例子全部说明java泛型中的K,V,T,E,?,object的意思及其用法
2013-03-07 11:09 70471.意思 jdk中的K,V,T,E等泛型名称很多人以为 ... -
Log4j 把不同包的日志打印到不同位置
2012-11-29 08:23 1149需要的包和测试的代码下载附件! 如果需要将不同的日 ... -
Java多线程发展简史
2012-09-16 14:25 1035转自:http://www.raychase.ne ... -
Java编码易疏忽的十个问题
2012-09-06 08:52 911在Java编码中,我们容易 ... -
网络编程
2012-09-04 13:30 970计算机网络基础 什么是计算机网络 把分布在 ... -
获取Java程序运行的路径 | 获取当前jar包的路径
2012-09-04 11:55 14077经过试验,不管是否是 Jar 包,不管是否是 Tom ... -
java的concurrent用法详解
2012-08-03 11:28 1017我们都知道,在JDK1.5之前,Java中要进行业务并发时 ... -
Java程序员必知的8大排序
2012-07-05 09:56 10268 种排序之间的关系: ... -
Comparator与Comparable的区别
2012-07-05 08:38 1217当需要排序的集合或数组不是单纯的数字类型的时候,通常可以使用C ... -
RSA算法Java实现
2012-06-27 08:22 1415Java代码 package c ... -
队列阻塞浅析
2012-06-17 18:10 930这几天所做的项目中涉及到了队列阻塞机制,通过研究整理如下 ... -
Java面试过程中会遇到的问题
2012-06-13 13:04 11431、abstract的method是否可同时是static,是 ... -
【解惑】深入jar包:从jar包中读取资源文件
2012-06-13 13:02 1099我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等)。 ... -
java 处理文件路径中的空格
2012-06-13 12:57 1537问题背景: windows下有个目录名称Program ... -
java内存分配机制
2012-06-13 12:52 1172通过这几天对一个 ... -
byte[]转化成其他数据类型
2012-05-14 16:41 1653Java与其他语言数据类型之间的转换方法实例程序 /*** ... -
java中byte转换int时为何与0xff进行与运算
2012-05-14 16:39 1070java中byte转换int时为何 ... -
java整型数与网络字节序的 byte[] 数组转换关系
2012-05-14 16:31 6458工作项目需要在 java 和 c/c++ 之间进行 ... -
利用 Base64 缩短 UUID 至22位
2012-04-15 18:57 7168UUID还是比较常用的,尤其在web应用里。 有时在UR ... -
图解Java中的值传递与引用传递(更新版)
2012-04-09 12:49 1178编程的人,都会遇到值传递与引用传递的困惑,不过很快都会迎 ...
相关推荐
在介绍双检锁模式(Double-Checked Locking Pattern,DCLP)的C++实现中,Scott Meyers和Andrei Alexandrescu在其2004年的文章中指出,传统的单例模式实现并不具备线程安全性。单例模式是设计模式中经常被提及的一种...
《C++ and the Perils of Double Checked Locking》是一篇探讨C++编程中双重检查锁定(Double-Checked Locking)模式潜在问题的文献。在多线程编程中,双重检查锁定是一种常见的优化策略,旨在减少对同步原语的依赖...
标题:C++与双检查锁定(Double Checked Locking)的陷阱 描述:C++如何解决单例模式的线程安全问题 ### 关键知识点解析: #### 单例模式的线程安全挑战 单例模式是一种设计模式,确保一个类只有一个实例,并提供...
双重检测锁(Double-Checked Locking)实现的Singleton模式在多线程应用中有相当的价值。在ACE的实现中就大量使用ACE_Singleton模板类将普通类转换成具有Singleton行为的类。这种方式很好地消除了一些重复代码臭味,...
北京火龙果软件工程技术中心意图无论什么时候当临界区中的代码仅仅需要加锁一次,同时当其获取锁的时候必须是线程安全的,可以用DoubleCheckedLocking模式来减少竞争和加锁载荷。动机1、标准的单例。开发正确的有效...
在C++中实现单例,需要注意线程安全问题,可能会使用到静态成员变量、双重检查锁定(Double-Checked Locking)以及C++11的std::call_once和std::once_flag等工具来确保正确性。 第5章可能会讲解“工厂模式”...
例如,对于"Lazy Initialization"反模式,书中可能会介绍双重检查锁定(Double-Checked Locking)的原始实现及其存在的问题,然后提出基于 volatile 关键字的改进方案,以确保线程安全的延迟初始化。 同时,附带的...
2. **双重检查锁定(Double-Checked Locking)**:这种方法是在多线程环境下保证线程安全的单例。首先检查是否已经实例化,如果未实例化,则同步锁定构造函数,确保只有一个线程可以进入,然后创建实例。这种方式...
为了解决这个问题,可以采用双重检查锁定(Double-Checked Locking)的策略: ```cpp class Singleton { private: Singleton() {} static Singleton* instance; static std::mutex mtx; public: static ...
3. **双检锁/双重校验锁定(Double-checked Locking)**: 这种方式在多线程环境下性能较好,只有在首次创建实例时才进行同步。 ```cpp class Singleton { private: Singleton() {} volatile static bool ...
描述提到“单件技术模板里面提供了4种方案”,这可能包括经典的懒汉式(Lazy Initialization)、饿汉式(Eager Initialization)、双检锁/双重检查锁定(Double-checked Locking)以及静态内部类(Static Inner ...
在C++中,单例模式可以通过静态成员、枚举或双检锁(double-checked locking)来实现。在Qt中,QCoreApplication就是一个单例类的例子。 2. **工厂模式**:提供一个接口用于创建一系列相关或相互依赖的对象,而无需...
#### 三、双重检查锁定(Double-Checked Locking) **代码示例:** ```java public class Singleton { private volatile static Singleton instance; private Singleton() {} public static Singleton ...
为了解决这一问题,可以采用双重检查锁定(Double-Checked Locking)模式来确保线程安全性: ```cpp class Singleton { public: static Singleton* Instance() { if (_instance == nullptr) { lock_guard<mutex>...
在C++中实现单例设计模式有多种方法,常见的包括懒汉式(lazy initialization)、饿汉式(eager initialization)以及双重检查锁定(double-checked locking)等。懒汉式在第一次使用时才创建单例,饿汉式在程序启动...
- 双重检查锁定(Double-Checked Locking):在多线程环境下,确保单例在被多次请求时仍保持唯一性,同时减少同步开销。 - 饿汉式(静态常量):在类加载时立即创建实例,保证线程安全,但可能会浪费内存资源。 -...
- 双重检查锁定(Double-Checked Locking):在多线程环境中,只有在真正需要创建单例时才进行同步操作,减少锁的使用提高性能。 - 静态内部类或枚举:利用Java类加载机制来保证线程安全,是推荐的实现方式。 5. ...
2. 双重检查锁定(Double-Checked Locking):这是最常见的一种线程安全实现方式。在获取实例时先检查实例是否已经存在,若不存在再加锁并创建。这样可以减少不必要的同步开销。 3. 原子操作:利用C++11引入的std::...
它的实现通常采用双重检查锁定(Double-Checked Locking)或静态内部类方式。工厂方法模式则通过抽象工厂接口来创建对象,使得具体创建哪个类的对象可以在运行时决定。建造者模式用于构建复杂对象,通过一步一步构建...
- 单例模式确保一个类只有一个实例,通常使用双重检查锁定(Double-Checked Locking)或静态内部类方式实现。 这些面试问题覆盖了Java的基础语法、面向对象、集合框架、并发编程等多个方面,是Java程序员面试中...