เมื่อวัตถุเปลี่ยนสถานะความสามารถในการเข้าถึงการอ้างอิงถึงวัตถุอาจถูกวางไว้ในคิวอ้างอิง คิวเหล่านี้ถูกใช้โดยเครื่องเก็บขยะเพื่อสื่อสารกับรหัสของเราเกี่ยวกับการเปลี่ยนแปลงในการเข้าถึงวัตถุ คิวเหล่านี้เป็นวิธีที่ดีที่สุดในการตรวจจับการเปลี่ยนแปลงการเข้าถึงแม้ว่าเราจะสามารถตรวจจับการเปลี่ยนแปลงการเข้าถึงของวัตถุโดยตรวจสอบว่าค่าคืนของวิธีการเป็นโมฆะหรือไม่
วัตถุอ้างอิงสามารถเชื่อมโยงกับคิวเฉพาะเมื่อสร้าง แต่ละคลาสย่อยของการอ้างอิงมีตัวสร้างของแบบฟอร์มต่อไปนี้:
. การอ้างอิงความแข็งแรงสาธารณะ (T อ้างอิง t, ReferenceQueueq): วิธีนี้สร้างวัตถุอ้างอิงใหม่ด้วยวัตถุอ้างอิงที่กำหนดและลงทะเบียนวัตถุอ้างอิงไปยังคิวที่กำหนด การอ้างอิงที่อ่อนแอและการอ้างอิงที่อ่อนนุ่มจะถูกแทรกลงในคิวหลังจากตัวเก็บขยะขยะกำหนดว่าวัตถุอ้างอิงของพวกเขาจะป้อนสถานะความสามารถในการเข้าถึงเฉพาะที่พวกเขาเป็นตัวแทนและการอ้างอิงทั้งสองจะถูกล้างก่อนคิวการแทรก การอ้างอิงเสมือนจริงจะถูกแทรกเข้าไปในคิวหลังจากตัวเก็บขยะขยะกำหนดว่าวัตถุอ้างอิงได้เข้าสู่สถานะที่เข้าถึงได้เสมือนจริง แต่จะไม่ถูกล้าง เมื่อวัตถุอ้างอิงถูกแทรกลงในคิวโดยตัวเก็บขยะค่าคืนค่าของวิธีการรับจะเป็นโมฆะแน่นอนดังนั้นวัตถุจะไม่สามารถฟื้นคืนชีพได้
การลงทะเบียนวัตถุอ้างอิงลงในคิวอ้างอิงไม่ได้สร้างการอ้างอิงระหว่างคิวและวัตถุอ้างอิง หากวัตถุอ้างอิงของเราเองไม่สามารถเข้าถึงได้ก็ไม่สามารถแทรกลงในคิวได้ ดังนั้นแอปพลิเคชันของเราจำเป็นต้องรักษาข้อมูลอ้างอิงที่แข็งแกร่งไปยังวัตถุที่อ้างอิงทั้งหมด
คลาส ReferenceQueue มีสามวิธีในการลบการอ้างอิงในคิว:
วิธีการสำรวจความคิดเห็นอนุญาตให้เธรดสามารถสอบถามได้ว่าการอ้างอิงอยู่ในคิวและดำเนินการเฉพาะเมื่อมีการอ้างอิงอยู่ในคิวหรือไม่ วิธีการลบสามารถจัดการสถานการณ์ที่ซับซ้อน (น้อยกว่า) มากขึ้นซึ่งเธรดเฉพาะมีหน้าที่ในการลบการอ้างอิงจากคิวและดำเนินการที่เหมาะสม พฤติกรรมการปิดกั้นของวิธีการเหล่านี้เหมือนกับพฤติกรรมการบล็อกที่กำหนดไว้ในวัตถุรอ สำหรับการอ้างอิงเฉพาะเราสามารถสอบถามได้ว่าอยู่ในคิวด้วยวิธี isenqueued หรือบังคับให้เข้าคิวโดยเรียกวิธีการ enqueue แต่โดยปกติแล้วการเสียบแบบนี้จะทำโดยนักสะสมขยะ
การอ้างอิงเสมือนจริงในคิวอ้างอิงสามารถใช้เพื่อกำหนดว่าจะรีไซเคิลวัตถุได้เมื่อใด เราไม่สามารถเข้าถึงวัตถุใด ๆ ผ่านการอ้างอิงเสมือนจริงแม้ว่าวัตถุจะสามารถเข้าถึงได้ในรูปแบบอื่น ๆ เพราะวิธีการของการอ้างอิงเสมือนจริงจะส่งคืนค่า NULL เสมอ ในความเป็นจริงการใช้การอ้างอิงเสมือนจริงเพื่อค้นหาวัตถุที่จะรีไซเคิลเป็นวิธีที่ปลอดภัยที่สุดเนื่องจากการอ้างอิงที่อ่อนแอและการอ้างอิงที่อ่อนนุ่มจะถูกแทรกเข้าไปในคิวหลังจากวัตถุสามารถยกเลิกได้ในขณะที่การอ้างอิงเสมือนจริงจะถูกแทรกลงในคิวหลังจากการสิ้นสุดของวัตถุ หากเป็นไปได้ควรใช้การอ้างอิงเสมือนจริงเสมอเพราะการอ้างอิงอื่น ๆ จะมีความเป็นไปได้ที่วิธีการที่สรุปใช้วัตถุที่ผ่านมาได้
พิจารณาตัวอย่างของตัวจัดการทรัพยากรที่สามารถควบคุมการเข้าถึงคอลเลกชันทรัพยากรภายนอก วัตถุสามารถขอการเข้าถึงทรัพยากรภายนอกและไม่สิ้นสุดการเข้าถึงจนกว่าการดำเนินการจะเสร็จสมบูรณ์หลังจากนั้นควรส่งคืนทรัพยากรที่ใช้ในตัวจัดการทรัพยากร หากทรัพยากรนี้ถูกแชร์สิทธิ์การใช้งานของมันจะถูกส่งผ่านระหว่างวัตถุหลาย ๆ ชิ้นและอาจส่งผ่านระหว่างหลายเธรดดังนั้นจึงเป็นเรื่องยากสำหรับเราที่จะพิจารณาว่าวัตถุใดเป็นผู้ใช้สุดท้ายของทรัพยากรนี้ เพื่อจัดการกับสถานการณ์นี้ตัวจัดการทรัพยากรสามารถบรรลุการรีไซเคิลทรัพยากรนี้โดยอัตโนมัติโดยเชื่อมโยงทรัพยากรกับวัตถุพิเศษที่เรียกว่าคีย์ ตราบใดที่วัตถุสำคัญสามารถเข้าถึงได้เราคิดว่าทรัพยากรนี้ยังคงใช้งานอยู่ ตราบใดที่วัตถุสำคัญสามารถรวบรวมเป็นขยะทรัพยากรจะถูกปล่อยออกมาโดยอัตโนมัติ รหัสต่อไปนี้เป็นตัวแทนที่เป็นนามธรรมของทรัพยากรข้างต้น:
ทรัพยากรอินเตอร์เฟส {ใช้โมฆะ (คีย์วัตถุวัตถุ… args); โมฆะปล่อย (); -เมื่อได้รับทรัพยากรวัตถุสำคัญจะต้องจัดเตรียมให้กับตัวจัดการทรัพยากร สำหรับอินสแตนซ์ทรัพยากรที่ส่งคืนทรัพยากรนี้สามารถใช้งานได้หากได้รับคีย์ที่สอดคล้องกัน สิ่งนี้ทำให้มั่นใจได้ว่าหลังจากรีไซเคิลคีย์จะไม่สามารถใช้ทรัพยากรที่สอดคล้องกันได้อีกต่อไปแม้ว่าวัตถุทรัพยากรที่แสดงถึงทรัพยากรนี้อาจยังสามารถเข้าถึงได้ โปรดทราบว่าวัตถุทรัพยากรไม่ได้จัดเก็บการอ้างอิงที่แข็งแกร่งไปยังวัตถุสำคัญซึ่งมีความสำคัญเนื่องจากสิ่งนี้ป้องกันไม่ให้วัตถุสำคัญไม่สามารถเข้าถึงได้ทำให้ทรัพยากรไม่สามารถแก้ไขได้ การใช้งานทรัพยากรสามารถซ้อนกันในผู้จัดการทรัพยากร:
Private Static Class ResourceImpl ใช้ทรัพยากร {int keyhash; Boolean heantRelease = FALSE ResourceImpl (คีย์วัตถุ) {keyHash = system.identityHashCode (คีย์); // = ตั้งค่าความต้องการทรัพยากรภายนอก = true; } การใช้โมฆะสาธารณะ (ปุ่มวัตถุ, วัตถุ ... args) {ถ้า (system.identityhashcode (key)! = keyhash) โยน illeqalargumentException ใหม่ ("คีย์ผิด" //... ใช้ทรัพยากร} การปลดปล่อยโมฆะสาธารณะรหัสแฮชของวัตถุคีย์จะถูกเก็บไว้เมื่อสร้างทรัพยากรและเมื่อใดก็ตามที่มีการเรียกใช้วิธีการใช้งานจะตรวจสอบว่ามีการจัดเตรียมคีย์เดียวกันหรือไม่ การใช้ทรัพยากรที่เกิดขึ้นจริงอาจต้องมีการซิงโครไนซ์ แต่เพื่อความเรียบง่ายเราละเว้นพวกเขาที่นี่ วิธีการวางจำหน่ายมีหน้าที่รับผิดชอบในการปล่อยทรัพยากร สามารถเรียกได้โดยตรงโดยผู้ใช้ทรัพยากรหลังการใช้งานหรือโดยตัวจัดการทรัพยากรเมื่อไม่มีการอ้างอิงวัตถุคีย์อีกต่อไป เนื่องจากเราจะใช้เธรดอิสระเพื่อตรวจสอบคิวการอ้างอิงวิธีการวางจำหน่ายจะต้องซิงโครไนซ์และต้องอนุญาตการโทรหลายครั้ง
ตัวจัดการทรัพยากรจริงมีแบบฟอร์มต่อไปนี้:
Public Class ResourceManager {Final ReferenceQueue
วัตถุสำคัญสามารถเป็นวัตถุใด ๆ ซึ่งให้ความยืดหยุ่นที่ดีเมื่อเทียบกับการให้ตัวจัดการทรัพยากรกำหนดวัตถุคีย์ เมื่อมีการเรียกใช้วิธีการ GetResource วัตถุงานทรัพยากรใหม่จะถูกสร้างขึ้นและคีย์ที่มีให้กับวิธีการจะถูกส่งผ่านไปยังวัตถุ ResourceIMPL ใหม่ จากนั้นจะมีการอ้างอิงเสมือนจริงและวัตถุอ้างอิงคือคีย์ที่ส่งผ่านไปยังวิธีการและจากนั้นการอ้างอิงเสมือนนี้จะถูกแทรกลงในคิวอ้างอิงของผู้จัดการทรัพยากร วัตถุอ้างอิงและการอ้างอิงเสมือนที่สร้างขึ้นในตอนท้ายจะถูกเก็บไว้ในตารางการแมป ตารางการแม็พนี้มีสองวัตถุประสงค์: หนึ่งคือเพื่อให้วัตถุอ้างอิงเสมือนทั้งหมดสามารถเข้าถึงได้และอีกจุดหนึ่งคือการจัดหาวิธีที่สะดวกในการสืบค้นวัตถุทรัพยากรจริงที่เกี่ยวข้องกับการอ้างอิงเสมือนจริงแต่ละครั้ง (อีกทางเลือกหนึ่งคือ phantomreference subclass และจัดเก็บวัตถุทรัพยากรในฟิลด์)
หากวัตถุคีย์ไม่สามารถเข้าถึงได้ผู้จัดการทรัพยากรจะใช้เธรด "Reaper" แยกต่างหากเพื่อประมวลผลทรัพยากร วิธีการปิดระบบ "ปิด" นักสำรวจโดยการยกเลิกเธรด Harvester (ตอบสนองต่อการขัดจังหวะ) ทำให้วิธีการ getResource ในการโยนข้อยกเว้น lele-lllestateException ในการออกแบบที่เรียบง่ายนี้การอ้างอิงใด ๆ ที่เสียบคิวหลังจากปิด explorer จะไม่ถูกประมวลผล เธรดการเก็บเกี่ยวที่แท้จริงมีดังนี้:
คลาส reaperthread ขยายเธรด {โมฆะสาธารณะเรียกใช้ () {// ทำงานจนกว่าจะถูกขัดจังหวะในขณะที่ (จริง) {ลอง {อ้างอิง ref = queue.remove (); ทรัพยากร res = null; ซิงโครไนซ์ (ResourceManager.his) {res = refs.get (อ้างอิง); อ้างอิง ลบ (อ้างอิง); } res. release (); Ref.Clear (); } catch (interruptedException ex) {break; // ทั้งหมดเสร็จสิ้น}}}}ReaperThread เป็นคลาสภายในและเธรด Harvester ที่กำหนดจะทำงานจนกว่าตัวจัดการทรัพยากรที่เกี่ยวข้องจะถูกปิด บล็อกเธรดบนวิธีการลบจนกว่าจะมีการอ้างอิงเสมือนที่เกี่ยวข้องกับคีย์เฉพาะจะถูกแทรกลงในคิวอ้างอิง การอ้างอิงเสมือนนี้สามารถรับการอ้างอิงไปยังวัตถุทรัพยากรจากตารางการแมปจากนั้นคู่ "คีย์ต่อการอ้างอิง" นี้จะถูกลบออกจากตารางการแมป ทันทีหลังจากนั้นวิธีการวางจำหน่ายจะถูกเรียกใช้วัตถุทรัพยากรเพื่อปล่อยทรัพยากร ในที่สุด
การอ้างอิงเสมือนถูกล้างเพื่อให้คีย์สามารถรีไซเคิลได้
เป็นทางเลือกในการใช้เธรดอิสระการดำเนินการใด ๆ ที่เรียกวิธีการสำรวจความคิดเห็นในคิวอ้างอิงและเผยแพร่ทรัพยากรทั้งหมดที่มีคีย์กลายเป็นวิธีที่ไม่สามารถเข้าถึงได้สามารถแทนที่ด้วยวิธีการ GetResource "และวิธีการ Shutdow" สามารถใช้ในการดำเนินการสำรวจความคิดเห็นขั้นสุดท้าย ความหมายของตัวจัดการทรัพยากรจะขึ้นอยู่กับประเภททรัพยากรจริงและรูปแบบการใช้ทรัพยากร
การออกแบบโดยใช้คิวอ้างอิงมีความน่าเชื่อถือมากกว่าการออกแบบที่ใช้การยุติโดยตรง (โดยเฉพาะการอ้างอิงเสมือนจริง) แต่เราจำเป็นต้องจำไว้ว่าเวลาและที่ตั้งที่แน่นอนของวัตถุอ้างอิงที่แทรกลงในคิวอ้างอิงนั้นไม่แน่นอนและไม่แน่ใจว่าการอ้างอิงที่สามารถทำได้ทั้งหมดได้ถูกแทรกเข้าไปในคิวอ้างอิงหรือไม่เมื่อแอปพลิเคชันสิ้นสุดลง หากเราต้องการตรวจสอบให้แน่ใจว่าทรัพยากรทั้งหมดสามารถปล่อยออกมาก่อนที่แอปพลิเคชันจะสิ้นสุดลงเราต้องติดตั้งตะขอปิดการปิดที่จำเป็นหรือใช้โปรโตคอลอื่น ๆ ที่กำหนดโดยแอปพลิเคชันเพื่อให้แน่ใจว่าจะได้รับ