我知道每当垃圾收集器收集类实例时都会调用 Finalize() 。但是,当通过队列将类的实例传递给另一个线程时,我有点困惑。
假设这是 Thread1 的骨架:
for(i=0; i<1000; i++) {
Packet pkt = new Packet(); // instance of class
pkt.id = i;
thread2.queue.put(pkt);
}
然后,线程2将从队列中删除该数据包并执行冗长的操作。第二个线程是否获得数据包的“副本”,或者是否通过某种形式的引用?重要的是,如果是通过复制,则可以在线程 2 处理数据包之前调用线程 1 中创建的实例上的 Finalize()。如果是通过引用,我保证 Finalize() 只会针对数据包中的信息调用一次。
这个基本示例可能没有显示出重要性,但我在数据包中存储了一个 C 指针(来自 JNI),以便在处理完该对象后销毁一些内存。如果通过复制传递,内存可能会在第二个线程完成之前被销毁。如果它是通过引用传递的,那么只有当 GC 发现它不再被两个线程使用时才应该销毁它(我想要的行为)。如果不能保证后一种情况,我将不会使用 Finalize() 并使用其他东西,但它会更复杂。
最佳答案
第二个线程接收相同的实际对象实例。您可以避免过早完成。
它接收对象引用的副本(如果您想这样想的话)。
此外,当垃圾收集器发现对象已成为垃圾时,finalize
不一定会运行 - 虚拟机可以在以后的任何时间自由运行它,并在某个时间实际回收内存在那之后。您确实不能依赖 finalize
何时运行。然而,由于您关心的是知道在第二个线程完成对象之前finalize
不会被调用,所以这是无关紧要的。但值得了解!
关于java - 在这种情况下,什么时候会对我的类实例调用 Finalize() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6779019/