Как убить "хитрый" Thread?

 
0
 
Java
ava
dzheika | 08.10.2008, 17:29
несмотря на то, что методы stop() & destroy() устарели и небезопасны, даже они не помогают, есть ли какая-нибудь возможность разблокировать монитор, который захватил "поток-вредитель"?


public static void main(String[] args) throws Exception {

Thread thread = new Thread() {
@Override
public void run() {
System.out.println("started");
synchronized (this) {
while (true)
;
}
}
};
thread.start();
Thread.yield();
thread.stop(); //deprecated, unsafe
System.out.println("stoped");
}
Ответы (10)
ava
polosatij | 08.10.2008, 20:55 #


The interrupt() was created by sun as a solution sun came up for the problems of thread stop(), it should be the cannonical way to stop a thread.

так пробовал?

http://java.sun.com/j2se/1.5.0/docs/api/ja...tml#interrupt()
ava
Platon | 09.10.2008, 08:20 #
Цитата (dzheika @ 8.10.2008, 17:29 findReferencedText)
есть ли какая-нибудь возможность


System.exit(0);
ava
dzheika | 09.10.2008, 10:31 #
Цитата (polosatij @ 8.10.2008, 20:55)
The interrupt() was created by sun as a solution sun came up for the problems of thread stop(), it should be the cannonical way to stop a thread.



так пробовал?



http://java.sun.com/j2se/1.5.0/docs/api/ja...tml#interrupt()

мдя... я про stop "даже они не помогают", а interrupt так вообще только выставляет флаг и выкидывает эксепшион, если поток в режиме ожидания, так что interrupt не поможет даже в случае while(true); (без блокировки монитора с мьютексом текущего потока)

----
нет, System.exit(0); не катит, надо только поток грохнуть, дело в том, что приложение запускает некоторые задачи из "чужих" либ отдельным потоком, есть таймаут на выполнение =), а если допустить, что "чужая" либа содержит такой код, то ... то вот пока еще не знаю, что делать =) но имхо jvm может его прикончить, кстати, так же поток может отловить и ThreadDeath, да и вообще любой Throwable, проигнорировав его и продолжив какой-то цикл, который оказался с тупиковым условием выхода.
ava
Platon | 09.10.2008, 10:41 #
dzheika, не надо использовать тупые библиотеки, которые не могут работать нормально, или если это ваш код, просто приведите его в порядок.
ava
dzheika | 09.10.2008, 10:49 #
в реальном случае код мой smile и я такого точно не буду делать, а вообще сначала по хорошему посылается interrupt, потом join с некоторым временем на завершение, и если поток еще жив, тогда уже stop (вернее уже отказался от stop), просто обобщив задачу и рассмотрев такой случай, понял, что не могу на 100% убить поток.
ava
Mayk | 09.10.2008, 10:50 #
Цитата (Platon @ 9.10.2008, 14:41 findReferencedText)
dzheika, не надо использовать тупые библиотеки, которые не могут работать нормально, или если это ваш код, просто приведите его в порядок.

а если топик стартер пишет что-нибудь наподобие robocode, где запускаемый код по определению чужой?
ava
Platon | 09.10.2008, 10:55 #
Mayk, значит надо долбить саппорт, и говорить, что у них код гнилой.
ava
SoulKeeper | 09.10.2008, 13:01 #
Нуууу можно попробувать запускать задачи в форковой JVM, на подобии анта при fork=true, ну и грохать другой процесс при таймауте... Только вот это уже зависит от того что задачи должны делать.
ava
COVD | 09.10.2008, 14:45 #
Когда вы делаете запрос из браузера серверу и нет ответа в течении некоторого времени, браузер закрывает соединение и показывает соответствующую страницу об ошибке. А сервер, возможно, в это время продолжает работать над ответом. Аналогично и с задачей в отдельном потоке. Приложение не дождавшись ответа от потока должно продолжать свою работу, а поток может продолжать крутиться (только его результата уже никто не ждет) пока не помрет естественной смертью. Это обычная практика.

Если же проблема в том, что такой поток сильно нагружает систему и желание его остановить вызвано необходимостью освободить ресурсы компьютера, то разумно изолировать эти потоки ( решающие изолированные задачи да еще с помощью сторонних библиотек ! ) от приложения, а именно перенести в другое приложение или вообще на другую машину, т.е. выделить в отдельный сервис.
ava
Dims | 09.10.2008, 20:00 #
Что-то возникают сомнения, что stop() не останавливает поток. В документации ясно написано, что поток останавливается и все мониторы освобождаются.

Вероятно, проблема в чём-то другом, например, в правильном возобновлении работы других потоков после остановки вредителя или в нарушении целостности тех данных, с которыми работал поток-вредитель.

Добавлено позднее:
Из текста программы я вижу, что поток захватывает монитор на объект thread, что и является причиной зависания.

Метод stop работаем внутри synchronized(this), то есть, он не может даже начать работу.

Вообще, захватывать монитор на объект потока это нехарактерно.

Вот такой код работает:


public class Test01 {
public static void main(String[] args) throws Exception {

Thread thread = new Thread() {
@Override
public void run() {
System.out.println("started");
while (true) {
;
}
}
};
thread.start();
Thread.yield();
thread.stop(); //deprecated, unsafe
System.out.println("stoped");
}
}


Добавлено позднее:
Можно ещё вот так переписать:


public class Test01 {
public static void main(String[] args) throws Exception {

Thread thread = new Thread() {
@Override
public void run() {
System.out.println("started");
synchronized (this) {
while (true) {
;
}
}
}
};

Thread thread2 = new Thread(thread);
thread2.start();
Thread.yield();
thread2.stop(); //deprecated, unsafe
System.out.println("stoped");
}
}
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить