Как я понимаю, Класс исключений Java, конечно, не неизменен (методы как initCause
и setStackTrace
дайте некоторый ключ к разгадке это). Таким образом, это, по крайней мере, ориентировано на многопотоковое исполнение? Предположим, что один из моих классов имеет поле как это:
private final Exception myException;
Я могу безопасно подвергнуть это поле нескольким потокам? Я не готов обсудить конкретные случаи, где и почему эта ситуация могла произойти. Мой вопрос больше о принципе: я могу сказать, что класс, который выставляет поле Типа исключительной ситуации, ориентирован на многопотоковое исполнение?
Другой пример:
class CustomException extends Exception
{
...
}
Действительно ли этот класс ориентирован на многопотоковое исполнение?
Обратите внимание, что initCause ()
синхронизирован
, а setStackTrace ()
копирует свой параметр а затем выполняет одно задание.
Итак, Exception
, похоже, действительно реализовано с учетом безопасности потоков. Тем не менее, я бы с осторожностью относился к любому дизайну, в котором исключения обычно передаются между потоками (то есть по любой причине, кроме обработки очень серьезного состояния ошибки). Это просто неправильно.
Для Sun java 6 реализация throwable
initCause
является синхронизированной
, поэтому она потокобезопасна. { {1}} fillInStackTrace
тоже.
setStackTrace
равно , а не , но он создает защитную копию ввода, а затем назначает эту копию. Конечно, этот метод предназначен «для фреймворков rpc».
Пока ваше поле myException является окончательным или изменчивым, его можно использовать для совместного использования.
Я не верю, что какие-либо гарантии безопасности потоков предоставляются классами исключений Java.
Целью исключения является создание исключения при обнаружении условия и перехват при его обработке. По определению это должно происходить в одном потоке. Если вы разделяете экземпляр Exception между потоками, значит, вы используете его в целях, для которых он не был разработан. Это запутает ваших читателей и сделает вашу программу менее удобной в обслуживании. Вероятно, вам следует рассмотреть альтернативную структуру для того, для чего вы ее используете.
Я считаю, что безопасная публикация Throwables/Exceptions - это вполне обоснованный вопрос. Комментарий DJClayworth о том, что "если вы делите экземпляр Exception между потоками, значит, вы используете его не по назначению", не учитывает код управления задачами с Futures. Обычно рабочий поток выбрасывает исключение, и это исключение должно быть обработано другим потоком. В дополнение ко всем комментариям выше, в которых упоминаются синхронизированные методы Throwable, Future публикует исключения между потоками, поэтому я считаю, что это ожидаемая, безопасная и поддерживаемая функциональность.