Java: класс исключения является потокобезопасным? - PullRequest
8 голосов
/ 19 апреля 2010

Как я понимаю, класс исключений в Java определенно не является неизменным (такие методы, как initCause и setStackTrace дают некоторые подсказки об этом). Так это по крайней мере потокобезопасно? Предположим, у одного из моих классов есть поле вроде этого:

private final Exception myException;

Можно ли безопасно открыть это поле для нескольких потоков? Я не готов обсуждать конкретные случаи, где и почему эта ситуация может возникнуть. Мой вопрос больше о принципе: могу ли я сказать, что класс, который предоставляет поле типа Exception, является поточно-ориентированным?

Другой пример:

class CustomException extends Exception
{
   ...
}

Является ли этот класс потокобезопасным?

Ответы [ 5 ]

7 голосов
/ 19 апреля 2010

Обратите внимание, что initCause() - это synchronized, а setStackTrace() копирует свой параметр и затем выполняет одно присвоение.

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

1 голос
/ 10 мая 2010

Полагаю, что безопасная публикация Throwables / Exceptions - совершенно правильный вопрос. Комментарий DJClayworth о том, что «если вы делитесь экземпляром Exception между потоками, то вы используете его в целях, для которых он не предназначен», не учитывает код управления задачами с Futures. Обычно рабочий поток генерирует исключение, и это исключение должно обрабатываться другим потоком. В дополнение ко всем приведенным выше комментариям, в которых упоминаются синхронизированные методы Throwable, Future публикует исключения между потоками, поэтому я считаю, что можно с уверенностью сказать, что это ожидаемая, безопасная и поддерживаемая функциональность.

1 голос
/ 19 апреля 2010

Для реализации java 6 в Sun с возможностью сбрасывания

initCause - это synchronized, поэтому он безопасен для потоков. fillInStackTrace тоже.

setStackTrace - это , а не , но он делает защитную копию ввода и затем назначает эту копию. Конечно, этот метод "для фреймворков RPC".

Пока ваше поле myException является окончательным или изменчивым, оно должно быть в порядке.

0 голосов
/ 19 апреля 2010

Целью исключения является выбрасывание при обнаружении и обнаружении состояния при его обработке. По определению это должно происходить в одном потоке. Если вы делитесь экземпляром Exception между потоками, вы используете его для целей, для которых он не предназначен. Это запутает ваших читателей и сделает вашу программу менее удобной в обслуживании. Вероятно, вам следует рассмотреть альтернативную структуру для всего, для чего вы ее используете.

0 голосов
/ 19 апреля 2010

Я не верю, что какие-либо гарантии безопасности потоков предоставляются классами исключений Java.

...