2010-11-08 3 views
4

Я google решение для уничтожения потока java. И существует два решения:Как убить нить java?

  1. установить флаг
  2. использования Thread.interrupt

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

Так как я могу убить эту тему? Заранее спасибо.

+4

Вы дон Не нужно убивать его, просто дайте им покончить с собой ... – Landei

ответ

5

Thread.interrupt() - единственный безопасный метод, который обычно применим. Разумеется, вы можете использовать другие сигналы уровня приложения (такие как условная проверка изменчивой переменной) для самостоятельного завершения. Другие методы (например, все устаревшие методы Thread.xx) могут загрязнять состояние вашего приложения недетерминированными способами и требуют перезагрузки всего состояния приложения.

+4

Thread.interrupt - это только половина истории, поток, который вы прерываете, должен поддерживать политику прерывания, которая использует флаг прерывания ... его флаг, который вызывает Thread. прерывание сбрасывается. – Toby

+0

В большинстве случаев Thread.interrupt не убивает нить, а Thread продолжает продолжаться. В такой ситуации было бы лучшим решением. – Kathir

+0

@Kathir: Thread.interrupt отправляет InterruptedException в поток при блокировке. Это ваша работа - поймать и закрыть надлежащим образом. –

0

Вы можете попробовать Thread.stop(), но at your own risk. Оптимально, API, который вы вызываете, должен иметь способ прервать операцию, если это необходимо (для чего нужен Thread.interrupt(), если сам API не обеспечивает более чистый способ прервать его прогресс, попробовали ли вы это?).

0

Вы можете вызвать метод stop объекта Thread, но настоятельно рекомендуется, чтобы вы этого не сделали. Прочтите следующее: http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

Есть ли у вас свобода вносить незначительные изменения в API? Является ли этот блокирующий вызов CPU привязанным или связанным с IO? Если он привязан к IO, и если у вас есть доступ к базовому сокету/удаленному объекту связи, закрытие этого объекта может творить чудеса. Это, по крайней мере, лучше, чем , останавливая нить.

3

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

Лучшим решением является изменение сторонней библиотеки для ответа на Thread.interrupt. Если вы не можете, то опустите его и найдите/используйте лучшую библиотеку.

+0

Future + Callable – Basil

+0

Этот подход не позволяет принудительно остановить поток. Метод 'Future.cancel' использует' Thread.interrupt() ', и нам уже сказали, что' Thread.interrupt() 'не является решением. –

1

Создайте отдельный процесс и убейте его, используя объекты ОС. Вам нужно будет позвонить в «C», но это будет не очень много кода. Вы не сказали, на какой ОС вы работаете.

+0

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

0

В java.util.concurrent.FutureTask, механизм отмены блокировки по времени действует, как бросание java.util.concurrent.TimeoutException.

Вы можете проверить это, как если бы что-то было автоматически прервано таймаутом.

0

С Thread.stop() (по праву) устарел, как правило, это достигается установкой флага в значение true. Что-то вроде этого:

Calling Класс:

... 
workListExecutor.stop() 
... 

WorkListExecutor.класс:

boolean running = true; 

void stop(){ 
    running = false; 
} 

void run(){ 
    while (running) { 
    ... do my stuff ... 
    } 
} 

Это предполагает, что ваша нить имеет какую-то основную петлю (обычно это случай). Если код в вашем цикле слишком велик, вы можете периодически проверять, running по-прежнему true, и выручить, если это не так.

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

2

Я бы поставил позвонить сторонний API, который занимает много времени в Callable<DataTypeReturnedBy3rdPartAPI>, а затем выполнить его с SingleThreadExecutor указав таймаут.

После этого подхода, поток будет убит если вызов API третьей стороны занимает больше времени, чем timeOut, вот какой-то код, чтобы проиллюстрировать то, что я говорю:

ExecutorService executor = Executors.newSingleThreadExecutor(); 
try { 
    //================= HERE ================== 
    Future<Boolean> job = executor.submit(thirdPartyCallable); 
    executor.awaitTermination(timeOut, TimeUnit.SECONDS);  
    if(!job.isDone()) 
    logger.debug("Long call to 3rd party API didn't finish"); 
    //========================================= 
} catch (Exception exc) { 
    exc.printStackTrace();  
} finally { 
    if(!executor.isShutdown()) 
     executor.shutdownNow(); 
} 

} 

private static Callable<Boolean> thirdParytCallable = new Callable<Boolean>() { 
    public Boolean call() throws Exception { 
    //Call to long 3rd party API 
    //....... 
    for(long i = 0;i<99999991999999L;i++) { 
     Thread.sleep(10L);// Emulates long call to 3rd party API 
     System.out.print("."); 
    } 
    return Boolean.valueOf(true);//Data from 3rd party API 
    } 
}; 
+0

«Эффективная Java» 2-го издания Джошуа Блоха «Пункт 68: Предпочитают исполнителей и задачи для потоков – user454322

Смежные вопросы