Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Как убить "хитрый" Thread?


Автор: dzheika 8.10.2008, 16: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");
    }

Автор: 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/java/lang/Thread.html#interrupt()

Автор: Platon 9.10.2008, 08:20
Цитата(dzheika @  8.10.2008,  17:29 Найти цитируемый пост)
есть ли какая-нибудь возможность

Код

System.exit(0);

Автор: dzheika 9.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/java/lang/Thread.html#interrupt()

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

----
нет, System.exit(0); не катит, надо только поток грохнуть, дело в том, что приложение запускает некоторые задачи из "чужих" либ отдельным потоком, есть таймаут на выполнение =), а если допустить, что "чужая" либа содержит такой код, то ... то вот пока еще не знаю, что делать =) но имхо jvm может его прикончить, кстати, так же поток может отловить и ThreadDeath, да и вообще любой Throwable, проигнорировав его и продолжив какой-то цикл, который оказался с тупиковым условием выхода.

Автор: Platon 9.10.2008, 10:41
dzheika, не надо использовать тупые библиотеки, которые не могут работать нормально, или если это ваш код, просто приведите его в порядок.

Автор: dzheika 9.10.2008, 10:49
в реальном случае код мой smile и я такого точно не буду делать, а вообще сначала по хорошему посылается interrupt, потом join с некоторым временем на завершение, и если поток еще жив, тогда уже stop (вернее уже отказался от stop), просто обобщив задачу и рассмотрев такой случай, понял, что не могу на 100% убить поток.

Автор: Mayk 9.10.2008, 10:50
Цитата(Platon @  9.10.2008,  14:41 Найти цитируемый пост)
dzheika, не надо использовать тупые библиотеки, которые не могут работать нормально, или если это ваш код, просто приведите его в порядок. 

а если топик стартер пишет что-нибудь наподобие robocode, где запускаемый код по определению чужой?

Автор: Platon 9.10.2008, 10:55
Mayk, значит надо долбить саппорт, и говорить, что у них код гнилой.

Автор: SoulKeeper 9.10.2008, 13:01
Нуууу можно попробувать запускать задачи в форковой JVM, на подобии анта при fork=true, ну и грохать другой процесс при таймауте... Только вот это уже зависит от того что задачи должны делать.

Автор: COVD 9.10.2008, 14:45
Когда вы делаете запрос из браузера серверу и нет ответа в течении некоторого времени, браузер закрывает соединение и показывает соответствующую страницу об ошибке. А сервер, возможно, в это время продолжает работать над ответом. Аналогично и с задачей в отдельном потоке. Приложение не дождавшись ответа от потока должно продолжать свою работу, а поток может продолжать крутиться (только его результата уже никто не ждет) пока не помрет естественной смертью. Это обычная практика. 

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

Автор: Dims 9.10.2008, 20:00
Что-то возникают сомнения, что stop() не останавливает поток. В документации ясно написано, что поток останавливается и все мониторы освобождаются. 

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

Добавлено через 6 минут и 4 секунды
Из текста программы я вижу, что поток захватывает монитор на объект 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");
    }
}


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

Код

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");
    }
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)