2013-03-04 4 views
0

Итак, этот ресурс (http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html) предлагает установить бит прерывания в потоке, когда этот поток не имеет дело с самим прерыванием: «, чтобы код выше в стеке вызовов мог узнайте о прерывании и ответьте на него, если он захочет. "Зачем устанавливать бит прерывания в Callable

Предположим, что я использую ExecutorService для запуска чего-то другого потока. Я создаю Callable и передаю этот Callable в ExecutorService.submit(), который возвращает будущее. Если Callable прерывается и затем сбрасывает бит прерывания, связанное с ним Future не будет вызывать InterruptedException при вызове Future.get(). Итак, какова была бы цель установки прерванного бита в Callable, если это будущее - единственный способ, которым главный поток имеет доступ к порожденной теме.

class MyCallable implements Callable<String> { 
    @Override 
    public String call() { 
    while (!Thread.currentThread().isInterrupted()) { 
    } 
    Thread.currentThread().interrupt(); 
    return "blah"; 
    } 
} 

ExecutorService pool = makeService(); 
Future<String> future = pool.submit(new MyCallable()); 
// Callable gets interrupted and the Callable resets the interrupt bit. 
future.get(); // Does not thrown an InterruptedException, so how will I ever know that the Callable was interrupted? 

ответ

1

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

class MyCallable implements Callable<String> { 
    @Override 
    public String call() { 
    // ... 
    if(Thread.currentThread().isInterrupted()) { 
     throw new InterruptedException(); 
    } 
    return "blah"; 
    } 
} 

Обратите внимание, вы все равно не получите InterruptedException непосредственно из Future.get() в этом сценарии. поскольку она была выбрана вызываемой, она будет завернута в ExecutionException (это позволяет различать прерывание вызываемого и прерывание основного потока).

0

Прерывание нити должно заканчиваться, но менее хрупким способом, чем kill(). Прерванное состояние потока проверяется только во время различных операций блокировки.

Если ваша нить была прервана во время одной из этих операций, выбрасывается InterruptedException. Когда это произойдет, вы хотите выйти чистым, как можно быстрее. Итак, что должно делать Callable, если поток обслуживания исполнителя прерывается?

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

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

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