请高手帮忙解释下打?的代码,谢谢,还有就是为什么要判断2次,麻烦了package com.tj.singleton.threadsafe.dcl;//double-checked locking
//Danger! This implementation of Singleton not
//guaranteed to work prior to Java 5public class Singleton {
private volatile static Singleton uniqueInstance;//??????? private Singleton() {
} public static Singleton getInstance() {
if (uniqueInstance == null) {//???????? 1 time
synchronized (Singleton.class) {//????????
if (uniqueInstance == null) {//???????? 2 time
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
//Danger! This implementation of Singleton not
//guaranteed to work prior to Java 5public class Singleton {
private volatile static Singleton uniqueInstance;//??????? private Singleton() {
} public static Singleton getInstance() {
if (uniqueInstance == null) {//???????? 1 time
synchronized (Singleton.class) {//????????
if (uniqueInstance == null) {//???????? 2 time
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
public synchronized static Singleton getInstance() {
if (uniqueInstance == null)
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
要判断两次是他的程序写的不好,这样写更好。
加个同步是为了防止两个用户同时调用该方法,生成两个Singleton对象。
package com.tj.singleton.threadsafe.dcl;//double-checked locking
//Danger! This implementation of Singleton not
//guaranteed to work prior to Java 5public class Singleton {
private static Singleton uniqueInstance; private Singleton() {
} public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
或者:
package com.tj.singleton.threadsafe.dcl;//double-checked locking
//Danger! This implementation of Singleton not
//guaranteed to work prior to Java 5public class Singleton {
private static Singleton uniqueInstance = new Singleton(); private Singleton() {
} public static synchronized Singleton getInstance() {
return uniqueInstance;
}
}
你写的那个属于“双重检查成例”。在 阎宏 的《Java 与模式》中曾经提及。并且指出这样是不正确的。
大概的原因是:
new Singleton(); 实际上有两步操作:
1: JVM 对其进行实例化。
2: JVM 调用析构函数,对其进行初始化。
而这两步不是原子的。所以照你的代码。如果一个线程在 getInstance() 中执行了 new Singleton(); 此时如果只对 Singleton 进行了实例化。那么当第二个线程 1 time 处,得出 uniqueInstance !=null 的判断,此时将 uniqueInstance 返回。那么这个被返回的 uniqueInstance 并没有被初始化。所以双重检查成例不可取。
//Danger! This implementation of Singleton not
//guaranteed to work prior to Java 5public class Singleton {
private static Singleton uniqueInstance = new Singleton(); private Singleton() {
} public static Singleton getInstance() {
return uniqueInstance;
}
}
head first 设计模式
在对一个非同步变量进行访问时,如果发现了非法值,即lz例子中的null,
则立即获得锁,重新检查变量,如果仍然非法,则设置。
第二次判断非空,是为了防止第一次和第二次之间,变量的值被改变。另外没有必要把简单的单例搞的这么复杂,直接public class Singleton {
private final static Singleton uniqueInstance = new Singleton(); private Singleton() {
} public static Singleton getInstance() {
return uniqueInstance;
}
}就可以,在classloader初次加载的时候,会自动给加锁的
但是如果实现了自己的classloader,就另当别论了
这中被称为“饿汉式单例模式”
有同步的那个事“懒汉是单例模式”
其同步的目的是“只创建一个对象”
由于在“饿汉式单例模式”中,在加载该类时,实例已经被创建(static 属性)。且在之后的操作中将不会再创建出新的实例,返回的实例,也将永远就是在加载该类是所创建的那个。
我java刚入门,你比我厉害多了