我很难理解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。我将非常感谢确认他们是真的,或解释为什么一个或多个是假的。
1条答案
按热度按时间rjzwgtxy1#
如果
A.finalize
先获取锁,然后a.o.getClass()
npe会加入吗C
. 最后的Assert是不正确的。就可达性而言,可以这样想:假设
A
以及C
是循环可到达的,则在“同时”将达到不可到达的。所以,这不可能是合理的A
必须在C
.我想一个直接的解决办法可能是参考计数
A
. 然而,依靠gc来清除非内存资源并不是件好事。