2013-11-18 4 views
1

Мне нужно прекратить выполнение потоков в ThreadPool, если любой из них выдает исключение. Мое решение - одно, ссылаясь на ExecutorService на каждый Runnable и называя shutdownNow(). Не уверен, что все в порядке. Реальный код является более сложным, поскольку он включает в себя отправку электронной почты в качестве задачи, но я упрощены для иллюстрации:Остановка всех потоков в ThreadPool, если возникло исключение

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.atomic.AtomicInteger; 

public class Concurrency { 
    private static AtomicInteger counter = new AtomicInteger(); 

    public static void main(String[] args) { 
     ExecutorService exec = Executors.newFixedThreadPool(5); 
     for (int i = 0; i < 20; i++) { 
      exec.execute(new Tasku(exec)); 
     } 
    } 

    public static class Tasku implements Runnable { 
     ExecutorService executorService; 

     public Tasku(ExecutorService executorService) { 
      this.executorService = executorService; 
     } 

     @Override 
     public void run() { 
      while (!Thread.currentThread().isInterrupted()) { 
       System.out.println(counter.incrementAndGet()); 
       if (counter.intValue() == 10) { 
        try { 
         throw new ArrayIndexOutOfBoundsException(); 
        } catch (ArrayIndexOutOfBoundsException e) { 
         executorService.shutdownNow(); 
        } 
       } 
      } 
     } 
    } 
} 

выше пример работает, после 10-го приращения счетчика он останавливается. Консольный выход:

1 
4 
6 
7 
5 
9 
3 
2 
10 
8 

Является ли это хорошим способом обработки сценария? Если нет, то как?

Thanks

+1

Почему вы бросаете, а затем перехватываете одно и то же исключение. Почему бы просто не называть 'shutdownNow()' напрямую? – dkatzel

+0

Имитация исключения, это может быть shutdownNow() только в этом примере, но в реальном коде ожидается исключение. – braincell

ответ

1

Это разумное решение. Вы можете улучшить его, переопределив Executor.exec (Runnable r) и отправив новую команду Tasku (r) вместо r. Таким образом, интерфейс Executor не изменился.

+0

Спасибо, но я не понял вашего предложения по улучшению, можете ли вы уточнить код? – braincell

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