когда будет вызываться finalize () для моего экземпляра класса в этом сценарии? - PullRequest
2 голосов
/ 21 июля 2011

Я знаю, что finalize () вызывается всякий раз, когда экземпляр класса собирается сборщиком мусора.Однако я немного запутался, когда передавал экземпляр класса другому потоку через очередь.

Допустим, это скелет потока 1:

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) в пакете, чтобы уничтожить часть памяти, когда я закончу с объектомЕсли он передается копией, память может быть уничтожена до того, как с ней завершит работу второй поток.Если он передается по ссылке, то он должен быть уничтожен только после того, как сборщик мусора обнаружит, что он больше не используется обоими потоками (мое желаемое поведение).Если этот последний сценарий не гарантирован, я не буду использовать finalize () и буду использовать что-то еще, но это будет более сложным.

1 Ответ

6 голосов
/ 21 июля 2011

Второй поток получает тот же фактический экземпляр объекта.Вы защищены от преждевременного завершения.

Он получает копию ссылки на объект, если вы хотите думать об этом таким образом.

Кроме того, finalize не обязательно запускается, когдасборщик мусора обнаруживает, что объект стал мусором - виртуальная машина может свободно запускать его в любое время и фактически восстанавливать память через некоторое время после этого.Вы действительно не можете рассчитывать, когда finalize будет запущен.Однако, поскольку вам важно знать, что finalize не будет вызвано до того, как второй поток завершит работу с объектом, это несущественно.Но стоит знать!

...