在这种情况下何时会在我的类实例上调用finalize()?

我知道每当垃圾收集器收集一个类实例时都会调用finalize()。 但是,当通过队列将类的实例传递给另一个线程时,我有点困惑。

假设这是Thread1的骨架:

for(i=0; i<1000; i++) { Packet pkt = new Packet(); // instance of class pkt.id = i; thread2.queue.put(pkt); } 

然后,线程2将从队列中删除数据包并执行冗长的操作。 这第二个线程是否获得了数据包的“副本”,还是通过某种forms的引用? 重要的是,如果它是通过复制,则可以在线程2完成数据包之前调用在线程1中创建的实例上的finalize()。 如果它是通过引用,我保证只对包中的信息调用finalize()一次。

这个基本示例可能没有显示重要性,但我在数据包中存储了一个C指针(来自JNI),以便在完成对象时销毁一些内存。 如果它是通过副本传递的,则内存可能会在第二个线程完成之前被销毁。 如果它是通过引用传递的,那么它应该只在GC看到BOTH线程不再使用它时才被销毁(我想要的行为)。 如果后一种情况得不到保证,我不会使用finalize()并使用其他东西,但会更复杂。

第二个线程接收相同的实际对象实例。 你过早结束是安全的。

它接收对象引用的副本,如果你想这样想的话。

此外,当垃圾收集器发现对象已变为垃圾时,不必运行finalize – VM可以在以后的任何时间自由运行它,并在此之后的某个时间实际回收内存。 你真的不能依赖于finalize时间。 但是,因为你关心的是知道在第二个线程完成对象之前不会调用finalize ,这是无关紧要的。 但值得知道!