Подтвердить что ты не робот

Guava: Throwables.propagate и InterruptedException

Какова наилучшая практика для обработки InterruptedException при использовании Throwables.propagate(e) в Guava?

Мне нравится использовать throw Throwables.propagate(e), особенно в методах, которые не выбрасывают исключенные исключения и где обработка исключений является ответственностью вызывающего. Но это не делает то, что я ожидаю с InterruptedException.

Я не хочу потерять тот факт, что поток был прерван, поэтому я в конечном итоге пишу такие вещи, как:

public void run() {
    Callable c = ...;
    try {
        c.call();
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw Throwables.propagate(e);
    } catch (Exception e) {
        throw Throwables.propagate(e);
    }
}

Есть ли способ сделать это в Гуаве? Есть ли способ (обратно совместимый?!) использовать нечто вроде Throwables.propagate(), которое устанавливает поток как прерванный, если он обертывает и распространяет InterruptedException?

4b9b3361

Ответ 1

Удобно, мы обсуждали это внутренне некоторое время назад. Я просто скопирую и вставляю:

Мое жесткое мнение о Throwables.propagate(e) заключается в том, что он в основном throw new RuntimeException(e) и что люди обычно не должны этого делать, как обычно не должны писать throw new RuntimeException(e). (И если они собираются написать это, они могут также написать его напрямую, чтобы он понял, что происходит.)

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

Мое твердое мнение о InterruptedException заключается в том, что реализация InterruptedException Exception вообще не выполняется так: это требует специальной обработки, которой нет в других исключениях.

Мое твердое мнение о преобразовании InterruptedException в RuntimeException - это "нет". (Это, как и большинство других вещей, которые я сказал выше, противоречиво.)

Итак, с одной стороны, я не уверен, что мы можем сделать, чтобы спасти propagate(). С другой стороны, может быть, неплохо сделать метод немного менее плохим.

Затем снова рассмотрим этого вызывающего, который ловит ExecutionException e:

throw Throwables.propagate(e.getCause());

Было бы неправильно прерывать поток потребителей, так как было бы неправильно бросать e.getCause() напрямую, потому что прерывание предназначалось для вычислительного потока, а не для потребительского потока.

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