"हाय, अमीगो!"

"हाय, ऋषि!"

"अच्छा, आपका दिन कैसा रहा?"

"शानदार! आज बिलाबो ने मुझे रिकर्सन के बारे में बताया, और ऐली ने मुझे कमजोर और नरम संदर्भों के बारे में बताया।"

"क्या उसने आपको प्रेत संदर्भों के बारे में बताया?"

"क्या आप फैंटम रेफरेंस के बारे में बात कर रहे हैं? उसने इसका उल्लेख किया, लेकिन इसे विस्तार से नहीं बताया।"

"महान, तो मुझे उम्मीद है कि अगर मैं इस अंतर को भर दूं तो आपको बुरा नहीं लगेगा।"

"बेशक! मैं तुम्हारी बात खुशी से सुनूंगा, ऋषि!"

"महान। फिर मैं शुरू करूँगा।"

"प्रेत संदर्भ सभी के सबसे कमजोर संदर्भ हैं। उनका प्रभाव तभी होता है जब किसी वस्तु में प्रेत संदर्भों के अलावा कोई संदर्भ नहीं होता है।"

प्रेत संदर्भ - 1

"एक फैंटम रेफरेंस का उपयोग एक जटिल वस्तु विलोपन प्रक्रिया में किया जाता है।  यह तब आवश्यक हो सकता है जब कोई वस्तु जावा मशीन के बाहर कुछ करती है, उदाहरण के लिए यह निम्न-स्तरीय OS फ़ंक्शंस को कॉल करती है या अपनी स्थिति को फ़ाइल में लिखती है या कुछ और बहुत महत्वपूर्ण करती है।"

"आप इसका उपयोग कैसे कर सकते हैं इसका एक उदाहरण यहां दिया गया है:"

प्रेत संदर्भ बनाने का उदाहरण
// 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));
}

"मैं फिर से अंतिम पंक्ति पर ध्यान आकर्षित करना चाहता हूं। न केवल ऑब्जेक्ट एक्स को फैंटम रेफरेंस में पास किया गया है - प्रेत संदर्भों की एक विशेष कतार भी है।"

"हमें इस कतार की आवश्यकता क्यों है?"

"वही जो मैं अब आपको बताने जा रहा हूँ।"

"जब आप प्रेत संदर्भ द्वारा रखी गई किसी वस्तु को नष्ट करते हैं, तो वह नष्ट हो जाती है, लेकिन यह स्मृति से नहीं हटाई जाती है! आप उसके बारे में क्या सोचते हैं?"

"तो वह कैसे काम करता है?"

"यहाँ कुछ बारीकियाँ हैं, इसलिए मैं सबसे सरल से शुरुआत करूँगा।"

"यदि किसी वस्तु का केवल प्रेत संदर्भ रहता है, तो उसके साथ यही होगा:"

" चरण 1। अगले कचरा संग्रह के दौरान, अंतिम रूप () विधि को वस्तु पर बुलाया जाएगा। लेकिन, यदि अंतिम रूप () विधि को ओवरराइड नहीं किया गया है, तो यह चरण छोड़ दिया जाता है, और चरण 2 को तुरंत निष्पादित किया जाता है। "

" चरण 2। अगले कचरा संग्रह के दौरान, वस्तु को प्रेत वस्तुओं की एक विशेष कतार में रखा जाता है। इसे इस कतार से हटा दिया जाएगा जब स्पष्ट () विधि को फैंटम रेफरेंस पर कहा जाता है।"

"इसे कौन बुलाता है? वस्तु हटा दी गई थी, है ना?"

"ठीक है, वस्तु वास्तव में हमारी दुनिया (जावा दुनिया) में मर गई थी, लेकिन यह गायब नहीं हुई है। यह एक प्रेत के रूप में बनी हुई है - प्रेत वस्तुओं की कतार अभी भी इसका संदर्भ रखती है। वही संदर्भ कतार जिसका संदर्भ हम बहुत सावधानी से रखते हैं फैंटम रेफरेंस कंस्ट्रक्टर को पास किया गया ।"

"तो यह संदर्भ कतार बाद के जीवन की तरह है?"

"एक प्रेत दुनिया की तरह अधिक।"

"और एक प्रेत वस्तु को केवल उसके प्रेत संदर्भ पर स्पष्ट () कॉल करके हटाया जा सकता है।"

"यहां बताया गया है कि पिछले उदाहरण को कैसे जारी रखा जाए:"

प्रेत संदर्भ बनाने का उदाहरण
// 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();
}

"मैं समझता हूं कि यहां कुछ हो रहा है। मैं लगभग ठीक-ठीक समझ भी रहा हूं कि क्या हो रहा है।"

"लेकिन आप व्यवहार में इसका उपयोग कैसे करते हैं?"

"यहाँ एक बेहतर उदाहरण है:"

प्रेत संदर्भ बनाने का उदाहरण
// 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));
}
यह धागा प्रेत कतार की निगरानी करेगा और उसमें से वस्तुओं को हटा देगा
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();
यह एक ऐसा वर्ग है जो PhantomReference को इनहेरिट करता है और इसके पास एक क्लोज़ () विधि है
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!");
 }
}

"हमने यहां तीन काम किए।"

"सबसे पहले, हमने PhantomInteger वर्ग बनाया , जो PhantomReference < पूर्णांक > को इनहेरिट करता है।"

"दूसरा, इस वर्ग के पास एक विशेष करीबी () विधि है। इस विधि को कॉल करने की आवश्यकता है जो यह सब शुरू हुई।

"तीसरा, हमने एक विशेष थ्रेड घोषित किया: रेफरेंस थ्रेड । यह एक लूप में तब तक प्रतीक्षा करता है जब तक कि प्रेत कतार में कोई अन्य वस्तु दिखाई न दे। जैसे ही ऐसा होता है, थ्रेड प्रेत कतार से वस्तु को हटा देता है और इसके करीब () विधि को कॉल करता है। और फिर स्पष्ट () विधि। और बस इतना ही। प्रेत एक बेहतर दुनिया में जा सकता है। यह अब हमें हमारी दुनिया में परेशान नहीं करेगा।

"इतना दिलचस्प, लेकिन यह सब काम कर गया।"

"हम वास्तव में मरने वाली वस्तुओं की एक कतार पर नज़र रख रहे हैं, और फिर हम उनमें से प्रत्येक के लिए एक विशेष विधि कह सकते हैं।"

"लेकिन याद रखें, आप ऑब्जेक्ट पर विधि को कॉल नहीं कर सकते हैं।  आप इसका संदर्भ नहीं प्राप्त कर सकते हैं! PhantomReference की get() विधि हमेशा शून्य होती है। "

"लेकिन हम प्रेत संदर्भ प्राप्त करते हैं!"

"यहां तक ​​​​कि PhantomReference के एक उपवर्ग के अंदर भी, प्राप्त () विधि शून्य हो जाती है।"

"तो मैं केवल कन्स्ट्रक्टर में ऑब्जेक्ट का संदर्भ सहेजता हूं"

"आह। लेकिन ऐसा संदर्भ एक मजबूत संदर्भ होगा, और वस्तु प्रेत कतार में कभी खत्म नहीं होगी!"

"डांग। ठीक है, छोड़ दो। अगर यह असंभव है, तो यह असंभव है।"

"ठीक है, अच्छा। मुझे आशा है कि आपने आज के पाठ से कुछ मूल्यवान सीखा है।"

"हाँ, बहुत सारी नई सामग्री थी। और मुझे लगा कि मैं पहले से ही सब कुछ जानता हूँ। पाठ के लिए धन्यवाद, ऋषि।"

"आपका स्वागत है। बस इतना ही, जाओ आराम करो। लेकिन मत भूलना - आज शाम हमारे पास एक और सबक है।"