“this”如何逃脱Java中的构造函数?

我听说过由于对象构造不当而在非线程安全代码中发生这种情况,但我真的没有这个概念,即使在Goetz的书中阅读了。我想巩固我对这种代码气味的理解,因为我可能正在这样做,甚至没有意识到它。请在您的解释中提供代码以使其坚持下去,谢谢。


答案 1

示例 :在构造函数中,创建一个事件侦听器内部类(它具有对当前对象的隐式引用),并将其注册到侦听器列表中。
=> 因此,即使您的对象尚未完成其构造函数的执行,也可以由另一个线程使用。

     public class A {

      private boolean isIt;
      private String yesItIs;

      public A() {
        EventListener el = new EventListener() { ....};
        StaticListeners.register(el);
        isIt = true;
        yesItIs = "yesItIs";
      }
     }

稍后可能发生的另一个问题:对象A可以完全创建,可供所有线程使用,由另一个线程使用......除了该线程可以看到A实例已创建,yesItIs具有“yesItIs”值,但不是!信不信由你,这有可能发生!发生的事情是:isIt

=> 同步只有一半是关于阻塞线程,另一半是关于线程间可见性

选择Java的原因是性能:如果所有数据都与所有线程共享,则线程间可见性会扼杀性能,因此只有同步的数据才能保证共享...


答案 2

非常简单的例子:

public class Test
{
    private static Test lastCreatedInstance;

    public Test()
    {
        lastCreatedInstance = this;
    }
}