Java的MessageFormat类是线程安全的吗?(与SimpleDateFormat相比)

11
我知道SimpleDateFormat和NumberFormat不是线程安全的。
但其他的Format类,比如MessageFormat呢?
Fortify 360标记了使用"MessageFormat.format(String, Object...)"静态方法作为"Race Condition - Format Flaw"问题,但当我分析MessageFormat的源代码时,我发现在这个方法中,它创建了一个新的本地MessageFormat实例。
Java的MessageFormat类是线程安全的吗?
3个回答

12

MessageFormat 的 javadoc 说明:

消息格式不是线程安全的。 建议为每个线程创建单独的格式实例。如果多个线程同时访问格式,则必须在外部进行同步。

因此,正式地说,它不是线程安全的。

SimpleDateFormat 的文档也有相同的说法。

现在,文档可能只是保守,实际上在多个线程中它能正常工作,但这种风险不值得冒。


谢谢您展示JavaDoc,这对我来说足够了。当我查看MessageFormat的源代码时,更加清楚为什么它不是线程安全的。该类使用NumberFormat和DateFormat两个不是线程安全的类。 - user46915
不是这样的!请查看有关“同步”的文档。 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/MessageFormat.html 以下内容来自此链接: “消息格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一个格式,则必须在外部进行同步。” - Mosheer

9
如果您正在参考这种方法
public static String format(String pattern, Object... arguments)

根据javadoc中的描述,这是线程安全的,因为它创建了一个新的MessageFormat来进行格式化。

顺便说一下,在您的标题“SimpleThreadFormat”中有一个有趣的打字错误 :)


你对这个问题有什么看法?https://stackoverflow.com/questions/75874534/cwe-366-the-application-is-using-shared-resource-messageformat-format-in-a-way - Sorin Penteleiciuc

1
根据javadoc,MessageFormat对象不是线程安全的。您可以使用ThreadLocal为每个需要一个对象的线程创建一个单独的对象。
ThreadLocal<MessageFormat> threadLocalMessageFormat =
    new ThreadLocal<MessageFormat>() {
        @Override
        protected MessageFormat initialValue() {
            return new MessageFormat(pattern);
        }
    };

你可以使用threadLocalMessageFormat.get()来获取当前线程的MessageFormat

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