相关疑难解决方法(0)

什么是"未完全构建的对象"?

Goetz的Java Concurrency in Practice,第41页提到了this在构造过程中引用如何逃脱.一个"不要这样做"的例子:

public class ThisEscape {
    public ThisEscape(EventSource source) {
        source.registerListener(
            new EventListener() {
                public void onEvent(Event e) {
                    doSomething(e);
                }
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

this是通过doSomething(e)引用封闭ThisEscape实例的事实"逃避" .可以通过使用静态工厂方法(首先构造普通对象,然后注册侦听器)而不是公共构造函数(完成所有工作)来解决这种情况.这本书继续:

从构造函数中发布对象可以发布未完全构造的对象.这是真实的,即使是公布在构造函数中的最后一条语句.如果this参考在构造期间逃逸,则认为该对象未正确构造.

我不太懂.如果发布是构造函数中的最后一个语句,那么之前没有完成所有构建工作吗?怎么会是this由当时不是有效?显然有一些伏都教在那之后继续,但是什么?

java concurrency publishing this

25
推荐指数
2
解决办法
1689
查看次数

在链接构造函数时,JVM的隐式内存屏障如何表现?

参考我之前关于不完整构造对象的问题,我有第二个问题.正如Jon Skeet指出的那样,在构造函数的末尾有一个隐式的内存障碍,可以确保final所有线程都可以看到这些字段.但是如果构造函数调用另一个构造函数呢?在每个人的最后是否有这样的记忆障碍,或者只是在第一个被召唤的人的最后?也就是说,当"错误"解决方案是:

public class ThisEscape {
    public ThisEscape(EventSource source) {
        source.registerListener(
            new EventListener() {
                public void onEvent(Event e) {
                    doSomething(e);
                }
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

正确的一个是工厂方法版本:

public class SafeListener {
    private final EventListener listener;

    private SafeListener() {
        listener = new EventListener() {
            public void onEvent(Event e) {
                doSomething(e);
            }
        }
    }

    public static SafeListener newInstance(EventSource source) {
        SafeListener safe = new SafeListener();
        source.registerListener(safe.listener);
        return safe;
    }
}
Run Code Online (Sandbox Code Playgroud)

以下工作是否也会起作用?

public class MyListener {
    private final EventListener listener;

    private …
Run Code Online (Sandbox Code Playgroud)

java constructor jvm compiler-optimization memory-barriers

14
推荐指数
1
解决办法
1291
查看次数