Когда объект изменяет состояние его достижения, ссылка на объект может быть помещена в отсчета. Эти очереди используются коллекционером мусора для связи с нашим кодом об изменениях в доступности объектов. Эти очереди являются лучшим способом обнаружения изменений доступности, хотя мы также можем обнаружить изменения доступности объекта, проверив, является ли возвратное значение метода GET нулевым.
Справочные объекты могут быть связаны с конкретными очередями при построении. Каждый подкласс ссылок предоставляет конструкторы следующей формы:
.public Slink Shower (T STREHSCE, RESTERKQUEUEQ): Этот метод создает новый эталонный объект с данным эталонным объектом и регистрирует эталонный объект в заданную очередь. Слабые ссылки и мягкие ссылки вставляются в очередь после того, как сборщик мусора определяет, что их эталонные объекты входят в конкретное состояние достижения, которое они представляют, и обе ссылки очищаются до очереди вставки. Виртуальные ссылки также будут вставлены в очередь после того, как сборщик мусора определит, что его эталонные объекты ввели виртуальное достижимое состояние, но они не будут очищены. Как только эталонный объект будет вставлен в очередь коллекционером мусора, возвращаемое значение его метода GET определенно будет нулевым, поэтому объект никогда не может быть воскрес.
Зарегистрирование эталонного объекта в отсчета не создает ссылку между очередью и эталонным объектом. Если сам наш справочный объект становится недоступным, его нельзя вставить в очередь. Поэтому наше приложение должно поддерживать сильную ссылку на все ссылки на объекты.
Класс Reference questue предоставляет три метода для удаления ссылок в очереди:
Метод опроса позволяет потоке запрашивать, находится ли ссылка в очереди, и выполняет определенное действие, когда ссылка существует в очереди. Метод удаления может обрабатывать более сложные (менее распространенные) ситуации, когда выделенный поток отвечает за удаление ссылок из очереди и выполнение соответствующих действий. Блокирующее поведение этих методов такое же, как и блокирующее поведение, определенное в Object.Wait. Для конкретной ссылки мы можем запрашивать, находится ли он в очереди по его методу Isenqueed, или втянуть его в очередь, вызывая его метод Enqueue, но обычно этот вид закуливания выполняется коллекционером мусора.
Виртуальные ссылки в справочной очереди могут использоваться для определения того, когда объект может быть переработан. Мы не можем получить доступ к какому -либо объекту через виртуальные ссылки, даже если объект доступен другим способом, потому что метод GET виртуальной ссылки всегда возвращает NULL. Фактически, использование виртуальных ссылок, чтобы найти объект, который будет переработан, является самым безопасным способом, потому что слабые ссылки и мягкие ссылки будут вставлены в очередь после того, как объект может быть прекращен, в то время как виртуальные ссылки вставляются в очередь после завершения завершающего объекта, то есть в целях вставлена после последнего момента, когда объект может выполнить определенные операции, а это абсолютно. Если вы можете, всегда должны использоваться виртуальные ссылки, потому что другие ссылки будут иметь возможность, которая завершает методы использования конечных объектов.
Рассмотрим пример диспетчера ресурсов, который может контролировать доступ к внешним коллекциям ресурсов. Объекты могут запросить доступ к внешнему ресурсу и не прекращать доступ до завершения операции, после чего они должны вернуть ресурс, используемый для менеджера ресурсов. Если этот ресурс будет обмен, его права на использование будут переданы между несколькими объектами и могут даже быть переданы между несколькими потоками, поэтому нам трудно определить, какой объект является последним пользователем этого ресурса, и поэтому трудно определить, какой кусок кода будет отвечать за возврат этого ресурса. Чтобы справиться с этой ситуацией, менеджер ресурсов может достичь автоматической переработки этого ресурса, связывая ресурс с специальным объектом, называемым ключом. Пока ключевой объект доступен, мы думаем, что этот ресурс все еще используется; Пока ключевой объект можно собирать в качестве мусора, ресурс будет автоматически выпущен. Следующий код является абстрактным представлением вышеуказанных ресурсов:
Интерфейс ресурс {void Использование (ключ объекта, объект… args); void release (); }Когда ресурс получен, его ключевой объект должен быть предоставлен для менеджера ресурсов. Для возвращаемого экземпляра ресурса этот ресурс можно использовать только в том случае, если он получает соответствующий ключ. Это гарантирует, что после переработки ключа его соответствующий ресурс больше не может использоваться, даже если объект ресурса, представляющий этот ресурс, все еще может быть доступен. Обратите внимание, что ресурсный объект не хранит прочную ссылку на ключевой объект, что важно, поскольку это предотвращает не подлежат недоступному объекту, что приводит к тому, что ресурс невозможным. Реализация ресурса может быть вложена в менеджер ресурсов:
Частный статический класс ресурсы реализует ресурс {int keehash; boolean enessrelease = false resourceimpl (object key) {keyhash = system.identityhashcode (key); // = Установить внешний ресурс upsRelease = true; } public void Использование (ключ объекта, объект ... args) {if (system.identityHashCode (key)! = KeyHash) бросить новый IlleqalargumentException ("неправильный ключ" //... use resource} public synchronized void release () {if efectReleasХэш -код объекта ключа сохраняется при создании ресурса, и всякий раз, когда вызывается метод использования, он проверяет, предоставляется ли тот же ключ. Фактическое использование ресурсов также может потребовать синхронизации, но для простоты мы опускаем их здесь. Метод выпуска отвечает за выпуск ресурса. Это может быть вызван непосредственно пользователем ресурса после использования или менеджером ресурсов, когда объект ключа больше не ссылается. Поскольку мы будем использовать независимые потоки для мониторинга контрольной очереди, метод выпуска должен быть синхронизирован, и должно быть разрешено несколько вызовов.
Фактический менеджер ресурсов имеет следующую форму:
Public Final Class ResourceManager {Final Referenceueue
Ключевым объектом может быть любой объект, который дает пользователям ресурсов большую гибкость по сравнению с наличием диспетчера ресурсов назначения ключевых объектов. Когда будет вызван метод GetResource, будет создан новый объект MPL -ресурсной работы, а ключ, предоставленный методу, будет передан новому объекту ResourceImpl. Затем создается виртуальная ссылка, и его ссылочный объект является ключом, передаваемым методу, и затем эта виртуальная ссылка будет вставлена в очередь справочного менеджера ресурсов. Виртуальные ссылки и эталонные объекты, созданные в конце, будут храниться в таблице отображения. Эта таблица отображения имеет две цели: одна из них состоит в том, чтобы сохранить все виртуальные ссылочные объекты, а другая - предоставить удобный способ запроса фактического ресурса, связанного с каждой виртуальной ссылкой. (Альтернатива состоит в том, чтобы подкласс PhantomReference и хранить объект ресурса в поле.)
Если объект ключа становится недоступным, диспетчер ресурсов использует отдельный поток «Жнец» для обработки ресурса. Метод выключения «закройте» проводника путем завершения потока Харвестера (в ответ на прерывание), что приводит к тому, что метод getResource бросил исключение ille-llestateException. В этом простом дизайне любые ссылки, которые подключаются в очередь после закрытия исследователя, не обрабатываются. Фактическая поток компонента следующим образом:
Class Reaperthread Extends Thread {public void run () {// run до прерывания, пока (true) {try {refer ref = queue.remove (); Ресурс Res = null; синхронизированный (resourceManager.this) {res = refs.get (ref); рефс. удалить (ref); } res .release (); ref.clear (); } catch (прерывание Exception ex) {break; // Все выполнены}}}}Reaperthread - это внутренний класс, и данная поток компонента будет работать до тех пор, пока не будет закрыт диспетчер ресурсов, связанный с ним. Поток блокирует метод удаления до тех пор, пока виртуальная ссылка, связанная с конкретной ключом, не вставлена в контрольную очередь. Эта виртуальная ссылка может получить ссылку на объект ресурса из таблицы отображения, а затем эта пара «ключа к ссылке» будет удалена из таблицы отображения. Сразу же после этого метод выпуска вызывает на объект ресурса для выпуска ресурса. наконец,
Виртуальная ссылка очищается так, чтобы ключ можно было переработать.
В качестве альтернативы использованию независимых потоков, любая операция, которая вызывает метод опроса в очереди на справочную очередь, и выпускает все ресурсы, ключи которых стали недоступными, может быть заменена методом GetResource, а метод Shutdow »также можно использовать для выполнения окончательной операции опроса. Семантика менеджера ресурсов будет зависеть от фактического типа ресурсов и шаблона использования ресурсов.
Конструкции с использованием ссылок -очередей гораздо более надежны, чем конструкции, которые используют непосредственно (особенно виртуальные ссылки). Но мы должны помнить, что точное время и местоположение эталонного объекта, вставленного в очередь, не являются уверенными, и мы не уверены, были ли все подключаемые ссылки в очередь ссылки, когда приложение заканчивается. Если нам необходимо убедиться, что все ресурсы могут быть опубликованы до завершения приложения, мы должны установить необходимый крючок отключения или использовать другие протоколы, определенные приложением, чтобы убедиться, что это достигнуто.