我知道每当垃圾收集器收集类实例时都会调用 finalize() 。但是,当通过队列将类的实例传递给另一个线程时,我有点困惑。
假设这是 Thread1 的骨架:
for(i=0; i<1000; i++) {
Packet pkt = new Packet(); // instance of class
pkt.id = i;
thread2.queue.put(pkt);
}
然后,线程 2 将从队列中删除数据包并执行冗长的操作。这第二个线程是否获得了数据包的“副本”,还是通过某种形式的引用?重要的是,如果是通过复制,在线程 1 中创建的实例上的 finalize() 可以在线程 2 完成数据包之前调用。如果是通过引用,我保证 finalize() 只为数据包中的信息调用一次。
这个基本示例可能没有显示重要性,但我在数据包中存储了一个 C 指针(来自 JNI),以便在我完成对象时破坏一些内存。如果它通过副本传递,则内存可能会在第二个线程完成之前被破坏。如果它是通过引用传递的,那么它应该只在 GC 看到它不再被两个线程使用时才被销毁(我想要的行为)。如果不能保证后一种情况,我不会使用 finalize() 并使用其他东西,但它会更复杂。