请高手帮忙解释下打?的代码,谢谢,还有就是为什么要判断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;
}
}

解决方案 »

  1.   


       public synchronized static Singleton getInstance() {
            if (uniqueInstance == null) 
                 uniqueInstance = new Singleton();
              }
            return uniqueInstance;
        }
    要判断两次是他的程序写的不好,这样写更好。
    加个同步是为了防止两个用户同时调用该方法,生成两个Singleton对象。
      

  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 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 并没有被初始化。所以双重检查成例不可取。
      

  3.   

    第二种写错了,应该是: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 Singleton getInstance() {
            return uniqueInstance;
        }
    }
      

  4.   


    head first 设计模式
      

  5.   

    即所谓的双重检查,目的是为了尽可能少的使用同步以获得最好的并发性。
    在对一个非同步变量进行访问时,如果发现了非法值,即lz例子中的null,
    则立即获得锁,重新检查变量,如果仍然非法,则设置。
    第二次判断非空,是为了防止第一次和第二次之间,变量的值被改变。另外没有必要把简单的单例搞的这么复杂,直接public class Singleton {
        
        private final static Singleton uniqueInstance = new Singleton();    private Singleton() {
        }    public static Singleton getInstance() {
            return uniqueInstance;
        }
    }就可以,在classloader初次加载的时候,会自动给加锁的
    但是如果实现了自己的classloader,就另当别论了
      

  6.   

    对,不用同步~~~
    这中被称为“饿汉式单例模式”
    有同步的那个事“懒汉是单例模式”
    其同步的目的是“只创建一个对象”
    由于在“饿汉式单例模式”中,在加载该类时,实例已经被创建(static 属性)。且在之后的操作中将不会再创建出新的实例,返回的实例,也将永远就是在加载该类是所创建的那个。
      

  7.   


    我java刚入门,你比我厉害多了