Что такое java-эквивалент AggregateException из .net?

В .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); 
}

Ответы

Ответ 1

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

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

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;
    }

}

Ответ 3

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

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 (если он существует) - это любое исключение, которое было создано в связанной с ним задаче.

Ответ 4

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