Здравствуйте, vsb, Вы писали:
vsb>·>Распараллелить кусок кода, и вот теперь у тебя проблема как пробрасывать исключения между тредами и что с ними делать потом.
vsb>Проверяемые исключения были плохой идеей до лямбд.
vsb>В принципе я не вижу ничего, что мешало бы сделать лямбды с нормальными проверяемыми исключениями. Немного язык доработать пришлось бы, но ничего сверхестественного. И сейчас можно писать interface Runnable<E> { void run() throws E; }, но это работает только с одним исключением. Нужно было сделать непредставимый тип вроде SQLException | IOException, который бы присваивался типу E. Ну и спроектировать стримы с учётом этой фичи. И было бы нормально. Но это так, к слову.
Очень всё становится сложным и хитрым. Допустим, даже все исключения непроверяемые.
Было:
List<Result> doSomething(List<File> files) throws WhatExceptions??
{
var results = new ArrayList<Result>();
for(var f : files)
{
var data = readData(f);
var parsed = parseData(data);
if(!good(parsed)) continue;
var result = process(parsed);
results.add(result);
}
}
Хотим параллельно:
List<Result> doSomething(List<File> files) throws WhatExceptions??
{
return files.parallelStream()
.map(this::parseData)
.filter(this::good)
.map(this::process)
.toList();
}
И внезапно исключений может быть несколько. Как их композить?
Или было
Result doSomething(Input in) throws X, Y {
var r1 = calc1(in);//throws X
var r2 = calc2(in);//throws Y
return combine(r1, r2);
}
стало
Result doSomething(Input inp) throws X, Y {
var r1 = executor.submit(() -> calc1(inp));//future
var r2 = executor.submit(() -> calc2(inp));//future
return combine(r1.get(), r2.get());//throws here now!
}
И теперь исключение надо хз как выковыривать. И это простые примеры, если это всё разнесено по разным методам/etc, то бардак начинается.
Вся однообразность кода идёт лесом. А по сути исключения можно выразить как очередную монаду.