DatatypeConverter是线程安全的吗?

4
特别是,javax.xml.bind.DatatypeConverter.parseBase64Binary(String)方法是否线程安全?
3个回答

5

文档中没有任何关于该类是线程安全的建议。因此,我建议您假设它不是。

我建议您使用来自Apache Commons Codec的Base64,该文档中声明它是线程安全的。


2

根据我对源代码的阅读,该实现是线程安全的。

  • parseBase64Binary方法在共享的DatatypeConverterImpl对象上调用parseBase64Binary方法,并且该对象是惰性创建的。

  • 很容易看出这种惰性创建是线程安全的。(代码在另一个答案中...)

  • 检查DatatypeConverterImpl发现它没有实例变量,因此无法关注访问/更新实例状态的线程安全问题。

  • DatatypeConverterImpl.parseBase64Binary方法(反过来)调用static _parseBase64Binary方法。

  • _parseBase64Binary方法使用其输入(不可变)和引用线程限制对象的本地变量。唯一的例外是decodeMap变量,它是一个private static final数组。

  • decodeMap变量在类(静态)初始化期间初始化并安全发布。

  • 初始化后,decodeMap变量只能被读取。因此,不存在与更新相关的同步问题或内存模型“危险”。

当然,这种分析仅适用于我链接的类版本。其他版本可能不是线程安全的。(但源代码可供多个版本自由使用,因此您应该能够检查您正在使用的JAXP版本是否为线程安全。)


谢谢。我不明白为什么这个类不允许你构建一个单独的实例来避免这种问题... - Alex
嗯...大概是因为没有需要避免的问题。但按照这个逻辑,他们应该明确说明该方法是线程安全的。 - Stephen C

0

查看了 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() 方法是静态同步的。

1
是的,但是theConverter.parseBase64Binary(...)怎么办? - Alex
如果您查看源代码,theConverter实例是易失性的。 - Naili
好的,但我们仍然可能会遇到问题...来自Java并发教程:原子操作不能交错执行,因此可以在不担心线程干扰的情况下使用它们。然而,这并不能消除所有同步原子操作的需要,因为仍然可能存在内存一致性错误。 - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接