"Hi, Amigo!"

"Hi, Rishi!"

"Well, kumusta ang araw mo?"

"Brilliant! Ngayon sinabi sa akin ni Bilaabo ang tungkol sa recursion, at sinabi sa akin ni Ellie ang tungkol sa mahina at malambot na mga sanggunian."

"Sinabi ba niya sa iyo ang tungkol sa phantom references?"

"PhantomReference ba ang pinag-uusapan mo? Binanggit niya ito, ngunit hindi niya ito ipinaliwanag nang detalyado."

"Great, then I hope you won't mind if I fill this gap."

"Oo naman! Pakikinggan kita nang may kasiyahan, Rishi!"

"Great. Tapos sisimulan ko na."

"Ang mga sanggunian ng phantom ay ang pinakamahinang sanggunian sa lahat. May epekto lamang ang mga ito kung ang isang bagay ay walang anumang mga sanggunian maliban sa mga sanggunian sa phantom."

PhantomReference - 1

"Ang isang PhantomReference ay ginagamit sa isang kumplikadong pamamaraan ng pagtanggal ng bagay.  Maaaring kailanganin ito kapag ang isang bagay ay gumawa ng isang bagay sa labas ng Java machine, hal. ito ay tumatawag sa mga function ng mababang antas ng OS o nagsusulat ng estado nito sa isang file o gumawa ng ibang bagay na napakahalaga."

"Narito ang isang halimbawa kung paano mo ito magagamit:"

Halimbawa ng paglikha ng mga sanggunian sa phantom
// Special queue for phantom objects
ReferenceQueue<Integer> queue = new ReferenceQueue<Integer>();

// List of phantom references
ArrayList<PhantomReference<Integer>> list = new ArrayList<PhantomReference<Integer>>();

// Create 10 objects and add them to the list using phantom references
for ( int i = 0; i < 10; i++)
{
 Integer x = new Integer(i);
 list.add(new PhantomReference<Integer>(x, queue));
}

"Gusto kong bigyang pansin muli ang huling linya. Hindi lamang ang object x ay ipinapasa sa PhantomReference - isang espesyal na pila ng mga phantom reference ay pati na rin."

"Bakit kailangan natin itong pila?"

"Iyan ang sasabihin ko sa iyo ngayon."

"Kapag sinira mo ang isang bagay na hawak ng isang phantom reference, ito ay masisira, ngunit hindi ito natatanggal sa memorya! Ano sa tingin mo tungkol doon?!"

"So, paano ito gumagana?"

"Mayroong medyo ilang mga nuances dito, kaya magsisimula ako sa pinakasimpleng."

"Kung mananatili lamang ang phantom reference sa isang bagay, ito ang mangyayari dito:"

" Hakbang 1 . Sa susunod na pangongolekta ng basura, ang paraan ng finalize() ay tatawagin sa object. Ngunit, kung ang finalize() na paraan ay hindi pa na-override, ang hakbang na ito ay nilalaktawan, at ang hakbang 2 ay isasagawa kaagad."

" Hakbang 2 . Sa susunod na pagkolekta ng basura, ang bagay ay inilalagay sa isang espesyal na pila ng mga phantom na bagay. Ito ay tatanggalin mula sa pila na ito kapag ang clear() na paraan ay tinawag sa PhantomReference."

"Sino ang tumatawag? Nabura ang bagay, di ba?"

"Buweno, ang bagay ay talagang namatay sa ating mundo (ang Java world), ngunit hindi ito nawala. Ito ay nananatili bilang isang multo — ang pila ng mga bagay na multo ay may hawak pa ring reference dito. Ang parehong ReferenceQueue na ang sanggunian ay maingat nating sinusunod ipinasa sa constructor ng PhantomReference ."

"So itong ReferenceQueue ay parang kabilang buhay?"

"More like a phantom world."

"At ang isang phantom object ay maaari lamang tanggalin sa pamamagitan ng pagtawag sa clear() sa phantom reference nito."

"Narito kung paano ipagpatuloy ang nakaraang halimbawa:"

Halimbawa ng paglikha ng mga sanggunian sa phantom
// Special queue for phantom objects
ReferenceQueue<Integer> queue = new ReferenceQueue<Integer>();

// List of phantom references
ArrayList<PhantomReference<Integer>> list = new ArrayList<PhantomReference<Integer>>();

// Create 10 objects and add them to the list using phantom references
for ( int i = 0; i < 10; i++)
{
 Integer x = new Integer(i);
 list.add(new PhantomReference<Integer>(x, queue));
}

// Call the garbage collector and hope it will listen to us :)
// It should destroy all phantom reachable objects and put them in the queue
// of phantoms
System.gc();

// Get all objects from the queue
Reference<? extends Integer>referenceFromQueue;
while ((referenceFromQueue = queue.poll()) != null)
{
 // Display the object on the screen
 System.out.println(referenceFromQueue.get());

 // Clear the reference
 referenceFromQueue.clear();
}

"Naiintindihan ko na may nangyayari dito. Halos naiintindihan ko na nga ang nangyayari."

"Ngunit paano mo ito ginagamit sa pagsasanay?"

"Narito ang isang mas magandang halimbawa:"

Halimbawa ng paglikha ng mga sanggunian sa phantom
// Special queue for phantom objects
ReferenceQueue<Integer> queue = new ReferenceQueue<Integer>();

// List of phantom references
ArrayList<PhantomInteger> list = new ArrayList<PhantomInteger>();

// Create 10 objects and add them to the list using phantom references
for ( int i = 0; i < 10; i++)
{
 Integer x = new Integer(i);
 list.add(new PhantomInteger (x, queue));
}
Susubaybayan ng thread na ito ang phantom queue at aalisin ang mga bagay dito
Thread referenceThread = new Thread()
{
 public void run()
 {
  while (true)
  {
   try
   {
    // Get the new object from the queue. If there is no object, then we wait!
    PhantomInteger ref = (PhantomInteger)queue.remove();
    // Call the close method on it
    ref.close();
    ref.clear();
   }
   catch (Exception ex)
   {
    // Write errors to a log
   }
  }
 }
};
// Run the thread as a daemon
referenceThread.setDaemon(true);
referenceThread.start();
Ito ay isang klase na nagmamana ng PhantomReference at may close() na pamamaraan
static class PhantomInteger extends PhantomReference<Integer>
{
 PhantomInteger(Integer referent, ReferenceQueue<? super Integer> queue)
 {
  super(referent, queue);
 }

 private void close()
 {
  System.out.println("Bad Integer totally destroyed!");
 }
}

"Tatlong bagay ang ginawa namin dito."

"Una, ginawa namin ang klase ng PhantomInteger , na nagmamana ng PhantomReference < Integer >."

"Pangalawa, ang klase na ito ay may espesyal na close () na pamamaraan. Ang pangangailangang tawagan ang paraang ito ang nagpasimula sa lahat ng ito.

"Ikatlo, nagdeklara kami ng isang espesyal na thread: referenceThread . Naghihintay ito sa isang loop hanggang sa lumitaw ang isa pang object sa phantom queue. Sa sandaling mangyari ito, aalisin ng thread ang object mula sa phantom queue at tinatawag ang close () na pamamaraan nito. At pagkatapos ang clear() na pamamaraan. At iyon na nga. Ang multo ay maaaring lumipat sa isang mas mabuting mundo. Hindi na tayo guguluhin nito sa atin."

"Kaya kawili-wili, ngunit ang lahat ay nagtagumpay."

"Talagang sinusubaybayan namin ang isang pila ng mga namamatay na bagay, at pagkatapos ay maaari kaming tumawag ng isang espesyal na paraan para sa bawat isa sa kanila."

"Ngunit tandaan, hindi mo matatawag ang pamamaraan sa mismong bagay.  Hindi ka makakakuha ng sanggunian dito! Ang pamamaraang get() ng PhantomReference ay palaging nagbabalik ng null. "

"Ngunit namana namin ang PhantomReference!"

"Kahit sa loob ng isang subclass ng PhantomReference, ang get() method ay nagbabalik ng null."

"Kaya nagse-save lang ako ng reference sa object sa constructor"

"Ah. Ngunit ang ganoong sanggunian ay magiging isang StrongReference, at ang bagay ay hindi mapupunta sa phantom queue!"

"Dang. Okay, give up. Kung imposible, imposible."

"Okay, good. Sana may natutunan ka sa lesson ngayon."

"Oo, napakaraming bagong materyal. At akala ko alam ko na ang lahat. Salamat sa leksyon, Rishi."

"You're welcome. Iyon lang, mag-relax ka. Pero huwag mong kakalimutan — may leksyon pa tayo ngayong gabi."