引述[0]
双检测机制主要用于多线程环境下的延迟初始化,也经常和单件(Singleton)模式在一起使用。如果只讨论Singleton模式,不必这么麻烦。
下面是一段双检测锁代码:
// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
// other functions and members...
}
双检测机制不起作用的原因是对象(Helper)的创建和成员(helper)的初始化顺序是不确定的。比如,线程调用方法getHelper(),可以获取一个非空的helper的引用,但是可能发现helper对象成员的值不是正确的应该在构造函数执行之后的值。如果创建对象和初始化对象是一步执行(inline)的,那两者的顺序就无所谓。
在Symantec JIT的虚拟机上的测试验证了双检测的问题。比如下面的语句:
singletons[i].reference = new Singleton();
赋值操作是在构造函数之前执行的。
在Singleton模式下,如果可以只有一个对象,可以定义静态成员。文中给的例子是在一个单独的类中定义:
class HelperSingleton {
static Helper singleton = new Helper();
}
还可以使用线程本地存储(Thread Local Storage)解决双检测机制
class Foo {
/** If perThreadInstance.get() returns a non-null value, this thread
has done synchronization needed to see initialization
of helper */
private final ThreadLocal perThreadInstance = new ThreadLocal();
private Helper helper = null;
public Helper getHelper() {
if (perThreadInstance.get() == null) createHelper();
return helper;
}
private final void createHelper() {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
// Any non-null value would do as the argument here
perThreadInstance.set(perThreadInstance);
}
}
上面的代码显示可以保证每个线程的getHelper()是安全的和正确的。在Java5及以后的版本里,采用了新的内存模型,可
以使用volatile关键字修饰变量如下:
// Works with acquire/release semantics for volatile
// Broken under current semantics for volatile
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}
给变量添加volatile关键字,指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。而不是本地内存(比如机器的寄存器)。双检测机制联合使用volatile后,系统不允许对变量的写操作和之前的读写操作进行优化重排执行(reorder),同时,不会对读操作和之前的读写操作进行优化重排执行。
( the system will not allow a write of a volatile to be reordered with respect to any previous read or write, and a read of a volatile cannot be reordered with respect to any following read or write.)
结合代码,如果helper已经new出来,但是还没有运行构造函数,此时另外一个线程的访问会延后到构造函数执行完毕才成功。就是说如果已经开始对helper进行写操作(new及构造初始化),则读操作(获取引用)不会成功。也就是说,volatile 变量可以被看作是一种 “程度较轻的 synchronized。
一个极端的例子,如果对象是一个不可变对象(immutable object),所有的成员都是final的,双检测机制可以工作的很好,因为访问一个不可变对象和访问原生类型,比如int,float等32位对象是没有什么区别的,都是原子操作。
总结实现考虑
1. 如果只是在Singleton模式下,可以简单使用静态变量,不适用延迟加载,不会有任何问题
2. 如果一定想延迟加载,加上volalite关键字
3. 如果不记得volalite关键字,使用同步方式,不使用双检测。
别的语言
1. C++: 可以结合内存栅栏(memory barriers),思路类似Java中volalite的效果。代码好似从ACE中摘的,但是我看最新的ACE代码,Singleton实现没有发现这样使用,这个问题暂且存疑。
2. Erlang:上面说了这么多,这个问题在Erlang中完全不存在。Erlang的变量不会改变,程序逻辑的流转依靠消息。这也算是Erlang的一个优势吧。
参考:
0. The "Double-Checked Locking is Broken" Declaration http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
1. 正确使用volatile: http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
分享到:
相关推荐
机电双开锁,顾名思义,是指利用电子技术和机械结构相结合的方式实现的双保险开锁机制,这种设计广泛应用于安全系统、智能家居、工业自动化等领域。 文档可能涵盖以下关键知识点: 1. **机电一体化基础**:机电...
2. **双电源开关锁的原理**:详细解释双电源开关的工作机制,包括如何检测电源状态,如何进行安全切换,以及它在电子政务中的具体应用场景。 3. **电子政务的电力需求**:阐述电子政务系统对于电力供应的特殊要求,...
6. **警报系统**:如果检测到未经授权的尝试或异常情况,锁会触发警报通知管理员,及时采取措施。 7. **应急解锁机制**:在紧急情况下,例如火灾或电力故障,应有应急解锁机制,如物理钥匙或特殊操作,确保人员能...
容灾恢复计划是在遇到灾难性事件时,能快速恢复服务的关键,通常包括数据异地备份、紧急响应机制等。 此外,电子政务实施还涉及到法规遵循、公民隐私保护、政府信息公开等政策层面的问题。政府需要遵循相关的法律...
3. 双小键盘支持:在VB中,处理不同的键盘区(主键盘区和数字小键盘区)并不困难,因为每个按键都有其对应的虚拟键码(Virtual Key Code)。通过识别这些键码,可以区分来自主键盘还是小键盘的输入,进而实现对两个...
此外,这些操作可能受到操作系统安全机制的限制,如需要相应的权限或使用特殊的驱动程序。 总结来说,基于EPROCESS结构中双向链表的进程检测方法是内核级编程中的一种常见技术,能够提供深入的系统进程监控和分析...
4. **故障检测与切换**:系统需要有一个监控机制来检测主服务器的健康状态。当主服务器出现故障时,负载均衡器会自动将流量切换到备用服务器。这可以通过心跳检测、健康检查接口等方式实现。 5. **定时任务的双机...
传统的机械锁因为结构简单易破解而逐渐被淘汰,取而代之的是安全性更高、使用更灵活的电子锁。电子密码锁作为一种先进的安全设备,凭借其高度的保密性和灵活性,受到了广泛欢迎。 #### 二、总体方案设计 ##### 2.1...
本文档所讨论的电子密码锁采用基于74LS112双JK触发器的数字逻辑电路控制方案,相比于复杂的单片机控制方案,该方案更为简洁明了,易于实现。 ##### 1. 设计思路 - **用户输入接口**:设计了9个输入键,其中仅4个键...
本文将详细介绍一种基于数字逻辑电路的电子密码锁设计,该设计以74LS112双JK触发器为核心,通过精巧的电路设计,实现了一个既安全又实用的密码保护机制。 电子密码锁的核心在于其数字逻辑电路设计,而本设计中采用...
双动力驱动系统的设计还可能包括能量回收机制,将用户解锁时的操作转化为电能,为电池充电。这种方式既环保又能延长电池的使用寿命。当然,这也要求系统具有较高的智能化程度,能够合理分配和使用来自不同动力源的...
- **时间限制与自锁机制**:从第一次按键输入开始,若5秒内未成功解锁,电路将自动复位,进入自锁状态,同时触发报警信号,确保安全性。 - **状态指示**:通过红绿两色指示灯,直观显示锁具的开关状态,即红灯亮、...
电子锁是现代科技在安防领域的一个重要创新,它利用电子控制机制替代传统的机械钥匙,提供更高的安全性与便利性。 电子锁系统通常包括传感器、控制器和执行机构等组成部分。传感器负责检测用户的身份,如通过密码...
- **防锁定机制**:连续错误后锁定键盘,防止恶意破解。 - **时间限制**:限制输入密码的时间,避免长时间占用。 7. **电源管理** - **UPS电源**:备用电源系统能在主电源断电时维持系统运行,保证用户安全。 ...
4. **电源管理**:在电源监控电路中,迟滞比较器可以检测电压是否超出安全范围,触发保护机制。 5. **传感器接口**:在传感器系统中,迟滞比较器可以将模拟信号转换为数字信号,便于后续处理。 通过阅读《可调整式...
如果检测到未经授权的尝试,系统会立即报警,并可能采取锁定电子锁的措施,防止进一步的侵入。 此外,系统还可能具备动态密钥生成机制,每次解锁时都会生成一个新的加密密钥,增加了破解的难度。配合硬件安全模块...
本文档中的“双预防机制风险告知卡”详细列出了多个设备的风险点,包括真空包装机、金属探测仪、脱模机、生冰机、速冻库以及X射线检测仪,针对每个设备的风险点进行了分析和风险控制措施的制定。 1. **风险点分析**...
传感器则用于检测锁的状态和操作过程,为系统提供反馈。 这种结构的优点在于提高了安全性,因为没有正确的电子信号,锁芯无法与锁体结合,也就无法开启。同时,由于操作过程无需物理接触,电子锁还具有更好的耐用性...