2016-06-09 2 views
3

Этот код постоянно блокируется на future.get(). Я ожидал бы CancellationException или InterruptedException. Может кто-нибудь объяснить это?Выполнение JavaService.shutdownNow() не отменяет или прерывает поток

ExecutorService es = Executors.newSingleThreadExecutor(); 

es.execute(() -> { 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException e) {/*squelch*/} 
}); 

Future<Integer> future = es.submit(() -> 1); 
es.shutdownNow(); 
try { 
    future.get(); 
} catch (ExecutionException e) {e.printStackTrace();} 

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

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

+1

Задача 'future' никогда не запускается, но первая задача прервана. Таким образом, есть попытка остановить поток. – matt

ответ

2

В этом случае, похоже, не существует попытки остановить поток.

Он пытается остановить бег Runnables. В этом случае это, вероятно, тот, который спит. Это будет прервано, и вы поймаете исключение и вернетесь. NOP Runnable все еще находится в очереди.

Вы не получили бы InterruptedException, если поток, вызывающий future.get(), не был прерван.

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

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

Там две плохие обходные пути, чтобы получить эту возможность: отслеживать фьючерсы, которые вы получили назад и отменить их самостоятельно или отлитые в Runnables, которые были возвращены shutdownNow() на фьючерсы и отменить их, но это работает только потому, что происходит с внутренней реализацией исполнителя, которого вы используете.

Так что да, это поведение, это технически право, но это немного странно. Что вы пытаетесь сделать здесь?

+0

Благодарим вас за объяснение. Re: «Что вы пытаетесь выполнить» ... ничего. Я просто играл. – WoodenKitty

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