В частности, это метод javax.xml.bind.DatatypeConverter.parseBase64Binary(String)
потокобезопасный?Является ли DatatypeConverter потокобезопасным?
ответ
В документации нет ничего, что предполагает, что класс является потокобезопасным. Поэтому я рекомендую вам предположить, что это не так.
Я бы порекомендовал Base64
из Apache Commons Codec, который заявляет, что он безопасен для потока в документации.
После ознакомления с исходным кодом javax.xml.bind.DatatypeConverter.parseBase64Binary(String)
(JAXB api), который является статическим методом с использованием неизменяемого класса в качестве аргумента.
final public class DatatypeConverter {
...
// delegate to this instance of DatatypeConverter
private static volatile DatatypeConverterInterface theConverter = null;
...
public static byte[] parseBase64Binary(String lexicalXSDBase64Binary) {
if (theConverter == null) initConverter();
return theConverter.parseBase64Binary(lexicalXSDBase64Binary);
}
...
private static synchronized void initConverter() {
theConverter = new DatatypeConverterImpl();
}
...
}
Мы можем предположить, что он является потокобезопасным. Метод initConverter() статически синхронизирован.
Мое чтение source code таково, что , что реализация является потокобезопасной.
Метод
parseBase64Binary
вызываетparseBase64Binary
метод на общедоступномDatatypeConverterImpl
объект, который лениво создается.Легко видеть, что ленивое создание является потокобезопасным. (Код находится в другом Ответ ...)
Изучение
DatatypeConverterImpl
показывает, что она не имеет переменные экземпляра, поэтому не могут быть проблемы безопасности потоков над доступом/обновлением состояния экземпляра.Метод
DatatypeConverterImpl.parseBase64Binary
(в свою очередь) вызывает методstatic
_parseBase64Binary
.Метод
_parseBase64Binary
использует свой вход (который является неизменным) и локальные переменные, относящиеся к объектам, ограниченным потоком. Единственным исключением является переменнаяdecodeMap
, которая представляет собой массивprivate static final
.Переменная инициализируется и безопасно публикуется во время инициализации класса (статического).
После инициализации переменная
decodeMap
считывается только когда-либо. Таким образом, не может быть проблем с синхронизацией или «опасностей» модели памяти, связанных с обновлениями.
Конечно, этот анализ применим только к версии класса, к которому я привязан. Вполне возможно, что этот метод не является потокобезопасным в других версиях. (Но исходный код свободно доступен для нескольких версий, поэтому вы должны проверить это на версию JAXP, которую вы используете.)
Спасибо.Я не могу понять, почему этот класс не позволяет создавать отдельный экземпляр, чтобы избежать подобных проблем ... – Alex
Ну ... предположительно ... потому что нет никаких проблем, чтобы избежать. Но по этой логике они должны * указать *, что метод является потокобезопасным. –
Да, но как насчет 'theConverter.parseBase64Binary (...)' ?? – Alex
экземпляр theConverter является изменчивым, если вы посмотрели на исходный код – Naili
Хорошо, но у нас все еще могут быть проблемы ... взятые из учебника по параллелизму Java: «Атомные действия не могут чередоваться, поэтому их можно использовать, не опасаясь вмешательства потока Однако это не устраняет необходимость синхронизации действий атома, поскольку ошибки согласованности памяти все еще возможны ». – Alex