stevendu wrote:
//提供了一个供外部访问本class的静态方法,可以直接访问来达到创建一次的目的
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
//在getInstance内部作出了判断,达到只创建一次的目的
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance==null)
instance=new Singleton();
return instance;
}
}
这个模式比较好理解,但是也要注意某些情况下并不能达到Singleton的目的,比如说Singleton对象同时被不同的类装载器装载时,就如同Windows开发中如果要让某个程序只执行一次时,不能简单的判断窗口句柄是否存在一样,因为进程空间不同嘛。
上面所提到的第二部分的 code:
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance==null)
instance=new Singleton();
return instance;
}
}
比第一部份多了 if (instance==null)... 的判断
这样作的目地叫作 "lazy initialization".
如果该 field (instance) 是 static 的话
而且该 class (Singleton) 的目的就只是产生该 singleton 的话
那末事实上这个 if ... 的部分其实是多余的
直接用第一布分的 code:
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
就简单可达到 "lazy initialization" 的同样的功能了
因为只要没有 reference 到 Singleton class, static 的 instance 就不会被 initialized.
如果该 field (instance) 不是 static,
那才有必要考虑用 if ...... 的 code
Sample:
public class Singleton {
private SingletonHelper instance = null;
public synchronized SingletonHelper getInstance() {
if (instance==null) instance=new SingletonHelper();
return instance;
}
}
可是如此作的话, synchronized 会让 performance 变的很差
所以有改良品种:
public class Singleton {
private SingletonHelper instance = null;
public SingletonHelper getInstance() {
if (instance == null)
synchronized (this) {
if (instance == null) instance=new SingletonHelper();
}
return instance;
}
}
上面的 code 叫做 double-checked locking.
可惜的是 java 的 "double-checked locking" 并不 work.
目前有个 "JSR-133 Java Memory Model and Thread Spec" (http://www.cs.umd.edu/~pugh/java/memoryModel/CommunityReview.pdf) 正在进行中
并期望能解决这个 "broken double-checked locking" 的问题