Лучший способ определить и удалить заблокированную нить в Java

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

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

private void foo() throws Exception
{
        Runnable runnable = new Runnable()
        {

            @Override
            public void run()
            {
                    // stuff that could potentially lock up the thread.
            }
        };
        Thread thread;
        thread = new Thread(runnable);
        thread.start();
        thread.join(3500);
        if (thread.isAlive())
        {
            thread.stop();
            throw new Exception();
        }

}

3 ответа

Решение
public void stop() {
        if (thread != null) {
           thread.interrupt();
        }
    }

Смотрите эту ссылку на Как остановить тему, она хорошо освещает тему

Нет способа делать то, что вы хотите (безоговорочно). Например, если stuff that could potentially lock up the thread. Похоже, что остановить это невозможно, если не считать System.exit():

public void badStuff() {
 while (true) {
  try {
   wait();
  }
  catch (InterruptedException irex) {
  }
 }
}

Когда ваше приложение застревает, запустите jstack (или используйте отладчик). Попытайтесь выяснить, что блокирует функцию и исправьте ее.

Я бы посмотрел в java.util.concurrentExecutor рамки и, в частности, Future<T> интерфейс. с ними вы несколько отвлекаетесь от капризов java.lang.Thread, и вы получаете хорошее разделение того, что задачи, от того, как они выполняются (будь то в отдельном потоке, является ли поток из пула или создается в летать и т. д.)

Будущий экземпляр, по крайней мере, дает вам isDone а также isCancelled методы.

ExecutorService (подинтерфейс Executor) дает вам некоторые средства для завершения любых выдающихся задач. Или проверить ExecutorService.awaitTermination(long timeout, TimeUnit unit) метод

private void foo() throws Exception
{
        ExecutorService es = Executors.newFixedThreadPool(1);

        Runnable runnable = new Runnable()
        {

            @Override
            public void run()
            {
                    // stuff that could potentially lock up the thread.
            }
        };

        Future result = es.submit(runnable);

        es.awaitTermination(30, TimeUnit.SECONDS);

        if (!result.isDone()){
            es.shutdownNow();
        }

}
Другие вопросы по тегам