Я знаю, что finalize() вызывается всякий раз, когда сборщик мусора собирает экземпляр класса. Однако я немного смущен при передаче экземпляра класса в другой поток через очередь.
Допустим, это скелет Thread1:
for(i=0; i<1000; i++) {
Packet pkt = new Packet(); // instance of class
pkt.id = i;
thread2.queue.put(pkt);
}
Затем поток 2 удалит пакет из очереди и выполнит длительные операции. Получает ли этот второй поток «копию» пакета или это какая-то ссылка? Важно то, что, если это копия, finalize() экземпляра, созданного в потоке 1, может быть вызвана до того, как поток 2 завершит работу с пакетом. Если это по ссылке, мне гарантируется, что finalize() вызывается только один раз для информации в пакете.
Этот базовый пример может не отражать важность, но я сохраняю C-указатель (из JNI) в пакете, чтобы уничтожить часть памяти, когда закончу с объектом. Если он передается путем копирования, память может быть уничтожена до того, как второй поток завершит работу с ней. Если он передается по ссылке, то его следует уничтожить только после того, как GC увидит, что он больше не используется ОБОИМ потоком (мое желаемое поведение). Если этот последний сценарий не гарантирован, я не буду использовать finalize() и буду использовать что-то еще, но это будет более сложно.