作者提到,下面这样是不安全的发布:
public class LazyInitialization { private static Resourse resourse;

public static Resourse getInstance() {
if (resourse == null) {
resourse = new Resourse(1, "skywalker");
}
return resourse;
}
不安全的发布由于指令重排序的存在,有线程可能会看到未完全构造的对象,但是如何重现这个不安全的现象?下面是我的代码:
public class LazyInitialization { private static Resourse resourse;

public static Resourse getInstance() {
if (resourse == null) {
resourse = new Resourse(1, "skywalker");
}
return resourse;
}

private static class Worker implements Runnable {

private final CountDownLatch latch;

public Worker(CountDownLatch latch) {
this.latch = latch;
} @Override
public void run() {
try {
latch.await();
System.out.println(getInstance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(1);
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
new Thread(new Worker(latch)).start();
latch.countDown();
}

}public class Resourse { private int id;
private String name;

public Resourse(int id, String name) {
this.id = id;
this.name = name;
}

@Override
public String toString() {
return "Resourse [id=" + id + ", name=" + name + "]";
}执行多次,始终是正确的对象,到底如何才能重现作者说的未正确构造的现象?

解决方案 »

  1.   

    这个不同步产生的实例就已经是不唯一了,可以在toString里面调用下hashCode()看出来
    然后那个重排序好像是代码要经过JIT才会重排,不是热点代码好像没什么关系感觉...
    然后那个一般好像是说双重检查锁定这个方法不够用然后引出重排序这么个事,基本完全不懂只是不知道哪里看到过好像楼主可以搜下....
      

  2.   

    首先判断是不是同一个类,需要用实现hashcode方法。
      

  3.   

    未完全构造的对象?因为某些原因,会让new到一半的对象停止对属性赋值?然后仍能让引用指向对象吗?这个可能牵涉到jvm内部的一些细节了,不过挺有意思