Убивает ли будущий тайм-аут выполнение потока

При использовании объектов ExecutorService и Future (при отправке задач Runnable), если я укажу значение тайм-аута для будущей функции get, будет ли убит базовый поток, когда выдается TimeoutException?


person Nico Huysamen    schedule 26.04.2013    source источник


Ответы (4)


Это не. С чего бы это? Если ты не скажешь об этом.

Здесь есть очень серьезная проблема, например, в случае Callable. Если вы ждали результата, скажем, 20 секунд и не получили его, то результат вас больше не интересует. В это время вам следует вообще отменить задачу.

Что-то вроде этого:

Future<?> future = service.submit(new MyCallable());
    try {
        future.get(100, TimeUnit.MILLISECONDS);
    } catch (Exception e){
        e.printStackTrace();
        future.cancel(true); //this method will stop the running underlying task
    }
person Eugene    schedule 26.04.2013
comment
Просто комментарий: future.cancel(true); не останавливает выполняющуюся базовую задачу, он просто устанавливает для флага прерывания значение true для запущенного потока. Именно ваш код отвечает за проверку этого флага и выдачу исключения InterruptedException, если оно истинно. - person Thiago Kronig; 31.03.2015
comment
@ThiagoKronig, ты уверен? из документации, если вы передадите true, поток должен быть прерван и попытка завершится неудачей. - person Dirk; 27.07.2015
comment
@Dirk, из документации у нас есть: Если задача уже запущена, то параметр mayInterruptIfRunning определяет, должен ли поток, выполняющий эту задачу , быть прерван при попытке остановить задачу . Прерывание здесь означает, что он установит значение true для изменчивого флага этого потока. Выполняемый код должен проверить это условие, чтобы остановить себя. Код должен остановиться сам. - person Thiago Kronig; 28.07.2015
comment
@Thiago, не могли бы вы поделиться образцом кода / ссылкой на то, как кодировать внутри вызываемого объекта, можно проверить флаг? Что именно будет проверять код? - person mtk; 14.10.2019

Нет, это не так. Более того, нет даже попытки прервать задание. Во-первых, Future.get с таймаутом этого не говорит. Во-вторых, попробуйте мой тест, чтобы увидеть, как он себя ведет.

    ExecutorService ex = Executors.newSingleThreadExecutor();
    Future<?> f = ex.submit(new Runnable() {
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("finished");
        }
    });
    f.get(1, TimeUnit.SECONDS);

за 1 секунду он печатает

Exception in thread "main" java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:228)
    at java.util.concurrent.FutureTask.get(FutureTask.java:91)
    at Test1.main(Test1.java:23)

еще через 1 секунду задача успешно завершается

finished
person Evgeniy Dorofeev    schedule 26.04.2013
comment
Что ж ... эта конкретная Future реализация - нет. Поскольку это интерфейс, нельзя делать общих заявлений обо всех Future. - person Duncan Jones; 26.04.2013
comment
Future.get (long timeout, TimeUnit unit) не сообщает, что попытается остановить задачу. Кроме того, есть ли много способов остановить работающий поток? - person Evgeniy Dorofeev; 26.04.2013
comment
Хороший ответ, жалобу снимаю! - person Duncan Jones; 26.04.2013

Кажется, вам нужно явно убить, отменить или завершить задачу

Обработка исключений из задач Java ExecutorService

Как вернуть FutureTask после TimeoutException?

person gurvinder372    schedule 26.04.2013

Просто запустите эти две строки, программа никогда не завершится! :

    Future<?> f = Executors.newSingleThreadExecutor().submit(() -> System.out.println("done"));
    f.get(1, TimeUnit.SECONDS);
person Atul Kumar    schedule 16.06.2020
comment
Это не имеет отношения к вопросу. Фабрика потоков по умолчанию в SingleThreadExecutor возвращает поток, не являющийся демоном, поэтому он никогда не завершается. Демонические потоки - person M. S.; 27.07.2020