Что 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); 
}
15
задан Jonathon Faust 30 July 2010 в 20:23
поделиться

3 ответа

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

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

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
ответ дан 1 December 2019 в 04:33
поделиться

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

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

1
ответ дан 1 December 2019 в 04:33
поделиться

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

0
ответ дан 1 December 2019 в 04:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: