双重检查模式(DCL)问题

本来在上篇帖子里发了,不过没人回答,呵呵 做一个新的问题,问问大家怎么看。

effective java中文版一书中,在165页里说:

迟延初始化(lazy initialization)的双重检查模式(DCL):
private static Foo foo=null;
public static Foo getFoo(){
if(foo == null){
synchronized (Foo.class){
if(foo==null)
foo=new Foo();
}
}
return foo;
}
如果一个线程在不使用同步的情况下读入该引用,并调用被引用的对象上的方法,那么这个方法可能会看到对象被部分初始化的状态,从而导致灾难性的后果。

下面说道
一个线程看到一个被迟缓构建的对象处于部分初始化的状态,这种情形并不直观。在将引用发布到一个域(foo,其他的线程将从这个域读取它的值)中之前,对象应该被完整地构造出来,但是,在缺少同步的情况下,读入一个已“发布”的对象引用并不保证:一个线程将会看到在对象引用发布之前所有保存在内存中的数据。特别是,读入一个已发布的对象引用并不保证:读线程将会看到被引用的对象内部的最新数据值。一般情况下,双重检查模式并不能正确地工作,但是如果被共享的变量包含一个原语值,而不是一个对象引用,则它可以正常的工作[pugh01b].
我在《深入浅出设计模式(中文版)》第五章182页看到 对java5
用volatile修饰符可以解决这个问题。
请问大师能不能做个测试程序让我辈看看阿!

google 的blogspot 被封了 打不开这个连接。

看了banq给我的资料 万分感谢,但是有几个问题。
一, yohan 的这种生成类的方法 其实是破坏了原来类的构造器的私有属性,看下代码:
Singleton s = Singleton.getInstance();

Class<?> clazz = Singleton.class;

Constructor<?> cons = clazz.getDeclaredConstructor();
cons.setAccessible(true);

Singleton s2 = (Singleton) cons.newInstance ();
文章里说 这个是由于java类的生成 如果有两个load()的话,对同一个类 他们认为是不同的类,所以生成了两遍。可上面的代码哪里有两个load 呢?难道这个newInstance() 就是一个新的load吗?
这个可以说是一个黑客的做法 正常的程序里不应该有这样用的,是这样吗?请大师指点。
二。 用内部类确实可以解决这个问题,可为什么内部类可以解决这个问题?假设一的问题成立,则用内部类 也是有两个load() 这样也是会作为不同的类对待,应该不能避免阿,大师能解释一下吗?

DCL主要是因为,一个线程可能看到的引用时最新的,但是引用对应得对象的状态值却是过期的。没有通过syschronized保护的话,内存可见性和原子性没有办法保证。通过同步就可以保证,线程栈中的数据在进入同步块之前肯定已经被刷新到了主存中。