Какова связь между PhantomReference и ReferenceQueue?

У меня есть небольшая путаница по поводу PhantomReference в Java. Когда я просматривал онлайн-статьи, большинство из них упоминало, что объект PhantomReference вернет значение null после создания, даже если мы вызовем get() для ссылки, а также упомянул, что объекты достижимы фантомно, будут вставлены в ReferenceQueue, когда PhantomReference будет удален из память.

Я пробовал следующий пример кода, но у меня путаница в результате.

Equipment equipment = new Equipment();  
ReferenceQueue queue = new ReferenceQueue();  
PhantomReference pr = new PhantomReference(equipment, queue);

System.out.println(pr.get());  
System.out.println(queue.poll()); 

Над двумя утверждениями печатается ноль. Если pr.get() возвращает null, означает ли это, что объект, на который ссылается pr, является сборщиком мусора? Если это так, то почему объект еще не добавлен в очередь приоритетов?

Кто-нибудь может помочь, пожалуйста, мне уточнить это. Я извиняюсь от вас, если мое понимание неверно в отношении PhantomReference и ReferenceQueue.

Пожалуйста, опишите эти два термина просто

большое спасибо

1 ответ

Решение

PhantomReference#get() всегда возвращаетсяnull,

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

Вы не можете знать, было ли это собрано или нет get(),

Если это так, то почему объект еще не добавлен в очередь приоритетов?

Javadoc заявляет

Если сборщик мусора определит в определенный момент времени, что референт фантомной ссылки является фантомно достижимым, то в это время или в более позднее время он будет ставить ссылку в очередь.

Так что либо экземпляр не был мусором к тому времени poll() (неблокирующая) была вызвана или экземпляр был собран мусором, но соответствующий PhantomReference не был добавлен к ReferenceQueue,

Вы можете помочь этому, установив сильную ссылку на null и запрашивая GC, но также блокирует remove Reference из очереди.

equipment = null;
System.out.println(pr.get());
System.gc();
System.out.println(queue.remove()); // block and wait for it to be added
Другие вопросы по тегам