Как бросить бросок из финализаторов (объектов ресурса) - PullRequest
2 голосов
/ 10 сентября 2011

Финализаторы не являются деструкторами, финализаторы бесполезны.

Из того, что я слышал, многие объекты Java-ресурсов располагают в finalize () "на всякий случай".
Это кажется чрезмерно допустимым отношением, которое может привести к ошибкам.

Минимум, что вы хотели бы сделать, - это завершить, чтобы регистрировать ошибки (нераспределенные ресурсы во время завершения) и распечатывать их как стандартные, а затем удалять.
Более ограничительное отношение может заключаться в том, чтобы вместо этого сделать исключение. Я не обязательно собираюсь реализовывать такие ограничительные объекты ресурса, но я хотел бы знать, как это сделать.

Но в Java исключение, сгенерированное в финализаторе, игнорируется (за исключением того, что объект снова помещается в список для повторной финализации). Есть ли способ реализовать что-то подобное? Может быть, способ дать потоку, который создал объект, исключение из финализатора, если он все еще существует (или, возможно, родительские потоки, если нет?

Также !!!!! Как другие языки gc (особенно C #, python и т. П.) Имеют дело с финализацией ресурса (обычно они реализуют «на всякий случай» для классов ресурсов?), Выбрасывая из финализаторов, давая исключения другим потокам. (примечание: меня не волнует использование / использование сахара для вызова метода dispose или методов, принимающих замыкания, которые автоматически закрывают ресурс, меня интересует, какую роль играют финализаторы и распространение ошибок из финализаторов).

Ответы [ 2 ]

1 голос
/ 10 сентября 2011

Финализатор вызывается в отдельном потоке, поэтому создание исключения или ошибки ничего не даст, потому что вы не сможете перехватить исключение в своем коде или в одном из потоков.

Если выЕсли вы хотите передать исключения в другой поток, вы можете сделать это любым количеством способов.Однако мне не ясно, что вы будете делать в другой ветке, что вы будете делать в текущей ветке.то есть зачем создавать исключение для передачи другому потоку, чтобы оно превратилось в сообщение журнала, если текущий поток может записать сообщение в журнал.

0 голосов
/ 10 сентября 2011

Финализаторы сами по себе имеют массу и множество недостатков, от того, что на создание Объекта уходит больше времени, чтобы не тратить ресурсы, пока поток финализатора не вызовет метод финализации и так далее.

Единственная причина, по которой его следует использовать, - это принять меры предосторожности при утилизации ресурсов, скажем, у InputStream есть метод, который приводит к close (), теперь это никогда не может быть вызвано. Другой случай, когда его нужно использовать, это при использовании нативного. Нет абсолютно никакого другого случая, когда нужно это делать.

Теперь проблема с вашим желанием реализовать вышесказанное состоит в том, что говорят: существует объект с методом finalize (). Теперь, когда нет строгой ссылки на объект, он отправляется на сборку мусора. Теперь он проверяет из своей таблицы ввода, есть ли у этого конкретного объекта метод finalize () (который был отмечен при создании объекта в первую очередь). Теперь, когда поток финализатора запускает метод finalize (), и внутри этого метода есть блок кода, который в итоге привел к тому, что у этого метода есть сильная ссылка.

В следующий раз, когда тот же объект вызывается для сборки мусора, этот объект не отправляется в очередь финализатора второй раз (по умолчанию, поскольку ни один объект не может попасть в очередь финализатора более одного раза), следовательно, метод finalize () не вызывается второй раз. Это может привести к огромной проблеме.

Следовательно, если вы имеете дело с чем-то, убедитесь, что вы делаете это вне метода finalize (), а не в finalize (), поскольку это только приводит к проблемам и ничему другому

...