如果是single模式,则把Foo foo;改为static Foo foo;

解决方案 »

  1.   

    5.1.3 Double-Checked Locking
    This design pattern gained a fair amount of attention when it was first proposed, but it has been pretty thoroughly discredited by now. Still, it pops up every now and then, so here are the details for the curious.One case where developers are tempted to avoid synchronization deals with lazy initialization. In this paradigm, an object contains a reference that is time-consuming to construct, so the developer delays construction of the object:Foo foo;public void useFoo( ) {    if (foo == null) {        synchronized(this) {            if (foo == null)                foo = new Foo( );        }    }    foo.invoke( );}
    The developer's goal here is to prevent synchronization once the foo object has been initialized. Unfortunately, this pattern is broken because of the reasons we've just examined. In particular, the value for foo can be stored before the constructor for foo is called; a second thread entering the useFoo() method would then call foo.invoke() before the constructor for foo has completed. If foo is a volatile primitive (but not a volatile object), this can be made to work if you don't mind the case where foo is initialized more than once (and where multiple initializations of foo are guaranteed to produce the same value).For more information on the double-checked locking pattern as well as an extensive treatement of the Java memory model, see http://www.cs.umd.edu/~pugh/java/memoryModel/.
    就是完整的信息,看不明白,高人指点一下
      

  2.   

    这种写法的目的是避免在多线程环境下,对于每一个线程去调用useFoo()方法时,如果foo还没有被初始化,那么第一个调用此方法的线程将初始化foo引用,以后的线程就不用再作初始化。
    但是这里面存在的风险是,当第一个线程在 new foo() 对象时,意外中止,此时foo已经被部分初始化了,其他线程再调用useFoo()方法时,将使用一个指向处于部分初始化状态的对象,调用该对象上的方法,会发生不可预料的灾难~~
    这是我的理解,谢谢指正~