Убить объект в Java - PullRequest
       12

Убить объект в Java

1 голос
/ 30 марта 2011

В настоящее время я использую JMX для управления и мониторинга огромного процесса миграции, который выполняется в классе Java.

Я хотел бы иметь возможность прервать и завершить процесс, когда мне нужно, например, клиент / времятребуется, или в одной миграции произошел какой-то мертвый цикл.

Здесь мы вызываем abort изящным способом уничтожить поток, устанавливая логический флаг, и один раз каждый цикл сначала проверяет флаг, а затем решает, следует липродолжать или нет.Это было реализовано без каких-либо проблем.

Однако у меня возникли проблемы с уничтожением потока.Мой коллега предложил мне переопределить метод finalize () и попытаться уничтожить его внутри него.Тем не менее, я обнаружил в Интернете, что этот метод не сможет уничтожить объект, и он рекомендуется вызывать GC, но вместо этого пользователь.

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

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

Буду очень признателен за вашу помощь.

PS: отношение к JMX не означает, что оно действительно имеет отношение к JMX, просто мне бы хотелось, чтобы эта команда на убийство исходила из консольного клиента JMX.

Ответы [ 2 ]

2 голосов
/ 30 марта 2011

Немного трудно понять, что вы говорите, но я не думаю, что finalize поможет вам.

  • Действующий поток (т. Е. Тот, который был запущен и еще не завершен) доступен по определению и поэтому не будет собирать мусор.Поэтому добавление метода finalize к нему не окажет никакого влияния.

  • Если объект, о котором вы говорите, не является потоком, добавление finalize, вероятно, тоже не поможет:

    • Если выполняемый поток (или что-то еще) имеет ссылку на объект, это предотвратит сбор мусора.
    • Если этого не произойдет, и объект станет недоступным, метод finalize не будет запущен, пока GC не решит собрать объект ... и это может никогда не произойти.
    • Даже если вызывается метод finalize, что он может сделать?Вы уже сказали , что поток должен быть закрыт ... и ничего не произошло.

Реальная проблема здесь заключается в том, что потокне отвечает на ваш флаг «постепенного выключения».

  • Я бы попытался исправить это, используя Thread.interrupt() и Thread.isInterrupted() вместо пользовательского флага.Это дает преимущество в том, что прерывание также разблокирует такие вещи, как Thread.sleep Object.wait и некоторые операции ввода-вывода.

  • Если поток заблокирован, пытаясь установить связь с какой-либо внешней службой черезсокет или канал, вы можете разблокировать его, закрыв сокет и / или поток.Это, конечно, предполагает, что ваш код завершения работы может получить в свое распоряжение ссылку на объект Socket или Stream.

  • Если эти подходы не пройдены, я бы рассмотрел вопрос о подключении всей программы.позвонив по номеру System.exit() ... если это разумно.

  • Если вы полностью в отчаянии (и немного безумны), вы можете рассмотреть использование устаревшего метода Thread.abort(),Но существует определенная вероятность того, что это приведет к тому, что все ваше приложение будет сломано и не отвечает.Поэтому я бы НЕ рекомендовал этот подход.

Другие возможные варианты:

  • , что Поток действительно ответил и вышел, но ваш код выключения не заметил,
  • , что Поток умер до того, как вы пытались его отключить, а ваш код выключения не заметил,
  • , что Поток заблокирован,или
  • что существует некоторый длительный (но не бесконечный) цикл в исполняемом файле, который необходимо изменить для более частой проверки флага "Вы умрете сейчас".

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


Я думаю, вы сказали, что видели совет о том, что это была ПЛОХАЯ ИДЕЯ для вызова System.gc().Это хороший совет.

0 голосов
/ 30 марта 2011

Вы должны выполнить определенное задание в finally, которое вы хотите выполнить при выходе из метода в любом состоянии.Наиболее предпочтительный пример, который люди приводят по этому поводу, - это соединение с базой данных.

Да, рекомендуется оставить сборщик мусора на JVM.

JVM заботится об уничтожении объектов.

...