Что такое Java-эквивалент AggregateException из .net? - PullRequest
15 голосов
/ 31 июля 2010

В .net класс AggregateException позволяет создавать исключение, содержащее несколько исключений.

Например, вы хотите создать исключение AggregateException, если вы выполняли несколько задач параллельно, а некоторые из них не выполнялись с исключениями.

Есть ли в Java эквивалентный класс?

Конкретный случай, в котором я хочу использовать его:

public static void runMultipleThenJoin(Runnable... jobs) {
    final List<Exception> errors = new Vector<Exception>();
    try {
        //create exception-handling thread jobs for each job
        List<Thread> threads = new ArrayList<Thread>();
        for (final Runnable job : jobs)
            threads.add(new Thread(new Runnable() {public void run() {
                try {
                    job.run();
                } catch (Exception ex) {
                    errors.add(ex);
                }
            }}));

        //start all
        for (Thread t : threads)
            t.start();

        //join all
        for (Thread t : threads)
            t.join();            
    } catch (InterruptedException ex) {
        //no way to recover from this situation
        throw new RuntimeException(ex);
    }

    if (errors.size() > 0)
        throw new AggregateException(errors); 
}

Ответы [ 4 ]

9 голосов
/ 20 мая 2012

Java 7's Throwable.addSuppressed (Throwable) сделает что-то похожее, хотя оно было построено для немного другой цели ( try-with-resource )

3 голосов
/ 31 июля 2010

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

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

public class AggregateException extends Exception {

    private final Exception[] secondaryExceptions;

    public AggregateException(String message, Exception primary, Exception... others) {
        super(message, primary);
        this.secondaryExceptions = others == null ? new Exception[0] : others;
    }

    public Throwable[] getAllExceptions() {

        int start = 0;
        int size = secondaryExceptions.length;
        final Throwable primary = getCause();
        if (primary != null) {
            start = 1;
            size++;
        }

        Throwable[] all = new Exception[size];

        if (primary != null) {
            all[0] = primary;
        }

        Arrays.fill(all, start, all.length, secondaryExceptions);
        return all;
    }

}
1 голос
/ 31 июля 2010

Вы можете представить несколько задач как

List<Callable<T>> tasks

Тогда, если вы хотите, чтобы компьютер фактически выполнял их параллельно, используйте

ExecutorService executorService = .. initialize executor Service
List<Future<T>> results = executorService.invokeAll ( ) ;

Теперь вы можете перебирать результаты.

try
{
     T val = result . get ( ) ;
}
catch ( InterruptedException cause )
{
     // this is not the exception you are looking for
}
catch ( ExecutionExeception cause )
{
     Throwable realCause = cause . getCause ( ) // this is the exception you are looking for
}

Таким образом, realCause (если оно существует) является любым исключением, которое выдается в связанной задаче.

0 голосов
/ 31 июля 2010

Я действительно не понимаю, почему вы должны в первую очередь использовать исключения, чтобы пометить задачи как незавершенные / невыполненные, но в любом случае создать их самостоятельно не составит труда.У вас есть какой-нибудь код, чтобы мы могли помочь вам с более конкретным ответом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...