对象字段的终结

6ovsh4lw  于 2021-06-26  发布在  Java
关注(0)|答案(1)|浏览(251)

我很难理解JavaSE8语言规范第12.6.1节和第12.6.2节的含义。我正在使用一个产品,其中java对象管理本机对等点,因此正确地完成(直到我们有机会重写ref队列)非常重要。
很明显,从规范来看,终结器可能会无序运行。我很难做到这一点。
我相信说明书上说:

class A {
    public Object o = new Object()
    protected synchronized void finalize() throws Throwable { o = null; }
}

class B {
    A a = new A()
    protected void finalize() throws Throwable {
        a.getClass()   // always works: a cannot be null.
        a.o.getClass() // might NPE: a's finalizer might have been run
    }
}

class C {
    A a = new A()
    protected void finalize() throws Throwable {
        synchronized (a) {
            a.getClass()   // always works: a cannot be null.
            a.o.getClass() // always works: a.o cannot be null.
        }
    }
}

上面有4个Assert。我将非常感谢确认他们是真的,或解释为什么一个或多个是假的。

rjzwgtxy

rjzwgtxy1#

如果 A.finalize 先获取锁,然后 a.o.getClass() npe会加入吗 C . 最后的Assert是不正确的。
就可达性而言,可以这样想:假设 A 以及 C 是循环可到达的,则在“同时”将达到不可到达的。所以,这不可能是合理的 A 必须在 C .
我想一个直接的解决办法可能是参考计数 A . 然而,依靠gc来清除非内存资源并不是件好事。

相关问题