Как правильно остановить поток, если мой вызов Thread.interrupt() не сработает?

Общеизвестно, что нельзя останавливать запущенные процессы с помощью Thread.stop().

Обычно руководства и учебные пособия предлагают вместо этого использовать Thread.interrupt() или какую-либо логическую переменную и проверять изнутри кода это прерывание или переменную.

Но если у меня есть библиотечный метод, выполнение которого иногда занимает очень много времени, и я хочу дать пользователю возможность остановить этот процесс? И библиотека не дает мне механизмов для этого (не проверяет статус прерывания потока и нет переменных «стоп!»)?

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

Кажется, что Thread.stop() здесь единственное решение. Или, может быть, есть какое-то обходное решение?


person Rogach    schedule 26.04.2011    source источник
comment
см. этот пост forward.com.au/javaProgramming/HowToStopAThread.html   -  person Bala R    schedule 26.04.2011
comment
Сообщите об ошибке в системе отслеживания ошибок этой библиотеки.   -  person Guillaume Brunerie    schedule 26.04.2011
comment
Дубликат stackoverflow.com/q/4556401/1305344.   -  person Jacek Laskowski    schedule 11.03.2013


Ответы (5)


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

person jlew    schedule 26.04.2011
comment
Да, это хорошая альтернатива. Но порождение другого процесса (я полагаю, с помощью exec()?) не является кроссплатформенным и может быть очень тяжеловесным в Java - он будет потреблять ~ 100 МБ памяти только для запуска другой JVM. Я прав? - person Rogach; 26.04.2011
comment
Кроме того, это, вероятно, невозможно в среде апплета. - person Rogach; 26.04.2011

Почему вы не пытаетесь использовать сон (длительный тайм-аут), когда ждете какое-то условие, а если не получилось, вы просто «возвращаетесь» из потока?


Вероятно, ваш поток работает в while (booleanVariable) { },

если это так, вы можете установить эту переменную как volatile, а контроллер потока установить ее как false.

Думайте о Thread.stop() как о System.exit(value), это работает, но когда у вас есть какая-то ошибка, вызывающая остановку потока / выход из vm, будет гораздо сложнее найти ее.

person Pih    schedule 26.04.2011
comment
К вашему сведению, ваше предложение по редактированию было отклонено, потому что вы отредактировали свой собственный ответ в чужом ответе. Вместо этого я взял на себя смелость добавить его к этому ответу. - person zwol; 26.04.2011
comment
Извините, я пытался отредактировать свой вопрос. Мне нужно немного больше практики в stackoverflow. Извини :-) - person Pih; 26.04.2011
comment
Не беспокойся. Каждый когда-то был новичком на сайте. - person zwol; 26.04.2011

Единственное решение лучше, чем использование Thread.stop(), - это использовать библиотеку в отдельном потоке, который вы можете убить, чтобы остановить его.

person Peter Lawrey    schedule 26.04.2011
comment
И как убить нить? - person Rogach; 26.04.2011
comment
Он запускает поток для выдачи ошибки ThreadDeath, которая должна снимать блокировки и вызовы методов и молча игнорировать ошибку. Причина, по которой это небезопасно, заключается в том, что это может произойти в любом месте кода, что может привести к плохому состоянию. - person Peter Lawrey; 26.04.2011

Возможно, вы захотите найти разные дескрипторы функции, которую вы выполняете, например, если это ввод-вывод, вы можете попытаться закрыть любые открытые соединения/потоки. Если вы застряли с этой библиотекой (IE не может найти библиотеку с лучшей механикой прерывания), Thread.stop() — ваш единственный способ остановить поток.

person John Vint    schedule 26.04.2011

Thread.stop() устарел, начиная с java 4. Я прочитал статью, чтобы остановить поток, обернув вызов библиотеки в отдельный класс, который реализует InterruptibleChannel, который является частью java.nio. Interruptibleclasses имеет метод close(), с помощью которого другой поток может вызывать его асинхронно.

person prem sagar    schedule 26.04.2011
comment
Можно ссылку на ту статью? - person Rogach; 26.04.2011