Double-checked locking and the Singleton pattern
来源:互联网 发布:原生安卓手机推荐 知乎 编辑:程序博客网 时间:2024/06/07 00:24
Java单例模型非常常用,要实现单例,需要将相应的构造函数声明为private,然后通过静态方法getInstance()方法返回一个实例对象,这里有两种方法:
1、静态的对象直接初始化,调用静态方法getInstance()时直接返回
import java.util.*;class Singleton { private static Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; }}
2、与1不同,对象的初始化是在getInstance()方法中完成的,其中getInstance()比较复杂,所用技术就是Double-checked locking
import java.util.*;class Singleton{ private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized(Singleton.class) { //1 if (instance == null) //2 instance = new Singleton(); //3 } } return instance; }}
http://www.ibm.com/developerworks/java/library/j-dcl.html这篇文章详细讲解了Double-checked locking的来源以及出现的问题。
从程序代码角度来看,getInstance()可以完美的解决单例问题,既解决了首次方法调用的同步问题,同时也能保证以后的方法调用的未加入同步已解决性能问题。但文章指出事实并非如此,方法并不能完全保证方法的正确执行。其中涉及到构造函数instance = new Singleton()的底层实现:
mem = allocate(); //Allocate memory for Singleton object.instance = mem; //Note that instance is now non-null, but //has not been initialized.ctorSingleton(instance); //Invoke constructor for Singleton passing //instance.
instance可以在构造函数未执行前获得地址索引成non-null,当多个线程操作时变出现问题。这是编译器的乱序写问题,文章写于02年5月,其中提到的JIT compiler是Sun JDK 1.2.1,不是所有编译器都能够保证解决乱序写问题。
文章给出一个测试乱续写问题,验证String的不变性。不过本人用的是jdk6,跑了半天没跑出什么结果。
class StringCreator extends Thread {
MutableString ms;public StringCreator(MutableString muts) {ms = muts;}public void run() {while (true)ms.str = new String("hello"); // 1}}class StringReader extends Thread {MutableString ms;public StringReader(MutableString muts) {ms = muts;}public void run() {while (true) {if (!("hello".equals(ms.str))) // 2{System.out.println("String is not immutable!");break;}}}}class MutableString {public String str = "hello"; // 3public static void main(String args[]) {MutableString ms = new MutableString(); // 4new StringCreator(ms).start(); // 5new StringReader(ms).start(); // 6}}
文章最后指出单例模式最好选择两种方式:1、就是本文开始提到的第一种方法,2、是在getInstance()方法中初始化单例对象,但该方法需要声明为同步方法,即加个synchronized,优劣可想而知
- Double-checked locking and the Singleton pattern
- Double-checked locking and the Singleton pattern
- Double-checked locking and the Singleton pattern
- Double-checked locking and the Singleton pattern
- Double-checked locking and the Singleton pattern
- [转贴] Double-checked locking and the Singleton pattern
- 单例解析-Double-checked locking and the Singleton pattern
- Singleton pattern and problem with double checked locking
- Singleton优化(Double-Checked Locking Pattern)
- C++ and The Perils of Double-Checked Locking: Part I
- C++ and the Perils of Double-Checked Locking: Part II
- C++ and the Perils of Double-Checked Locking
- Singleton 模式和Double-Checked Locking
- The "Double-Checked Locking is Broken" Declaration
- The "Double-Checked Locking is Broken" Declaration
- The "Double-Checked Locking is Broken" Declaration
- The "Double-Checked Locking is Broken" Declaration
- The "Double-Checked Locking is Broken" Declaration
- 我的下一个设备是什么?
- Java内部类
- 解决VIM编辑中文文档 “编辑/命令” 模式输入法频繁切换问题
- 约瑟夫问题的数学解法
- 在windows上创建软链接解决Dropbox不能同步多个目录的问题
- Double-checked locking and the Singleton pattern
- Xcode 制作静态库
- 入门前的感触
- Dll注入技术之注册表注入
- [母函数]POJ 1221 UNIMODAL PALINDROMIC DECOMPOSITIONS
- 第21天 Android Touch事件学习 8 事件分发原理
- Spring MVC 3 深入总结
- 莫比乌斯反演初步
- 用css制作表单并体验亲和力