2014-10-08 4 views
1

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

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

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

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

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

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

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

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

ответ

2

PhantomReference#get()always returns null.

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

Вы не можете знать, было ли оно получено или нет через get().

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

The javadoc состояния

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

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

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

equipment = null; 
System.out.println(pr.get()); 
System.gc(); 
System.out.println(queue.remove()); // block and wait for it to be added 
+0

Спасибо за ваш ответ, и это помогло мне понять контекст яснее, но я хотел бы знать, почему вы вызываете System.gc(); а затем вызовите queue.remove(). Не могли бы вы объяснить это? – Dilan

+0

@ user3115189 'System.gc()' является _suggestion_ в сборщик мусора, чтобы мусор собирал все, что мог. Это дает нам больше шансов увидеть, что объект «Оборудование» является сборкой мусора. 'Очереди.remove() 'вызывается вместо' poll() ', потому что он блокирует ожидание того, что запись будет доступна в очереди. См. Цитату из javadoc в моем ответе. Фантомная ссылка может быть добавлена ​​в очередь через некоторое время ** **. Мы хотим подождать, пока это не произойдет. –

+0

Большое спасибо вам – Dilan

Смежные вопросы