为什么java.util.logging.Formatter中的formatMessage()方法是同步的?

为什么java.util.logging.Formatter中的formatMessage()方法是同步的?,java.util.logging,Java.util.logging,在用于格式化调试日志的抽象JDK类格式化程序中,formatMessage方法声明为已同步 然而,我还不能确定为什么会这样 显然,可以编写非线程安全的重写版本,但我想知道为什么默认实现不是线程安全的 [T] formatMessage方法声明为synchronized。但是,我无法确定为什么会出现这种情况 的早期版本尝试缓存资源束get字符串调用的结果,以避免构建java.util.MissingResourceException。同步用于保护用于缓存查找的HashMap 以下是版权所有的200

在用于格式化调试日志的抽象JDK类格式化程序中,formatMessage方法声明为已同步

然而,我还不能确定为什么会这样

显然,可以编写非线程安全的重写版本,但我想知道为什么默认实现不是线程安全的

[T] formatMessage方法声明为synchronized。但是,我无法确定为什么会出现这种情况

的早期版本尝试缓存资源束get字符串调用的结果,以避免构建
java.util.MissingResourceException
。同步用于保护用于缓存查找的
HashMap

以下是版权所有的2004 Sun Microsystems,Inc.版本1.16,12/19/03源代码,请注意注释:

public synchronized String formatMessage(LogRecord record) {
    String format = record.getMessage();
    java.util.ResourceBundle catalog = record.getResourceBundle();
    if (catalog != null) {
        // We cache catalog lookups.  This is mostly to avoid the
        // cost of exceptions for keys that are not in the catalog.
    //      if (catalogCache == null) {
    //      catalogCache = new HashMap();
    //      }
    //      format = (String)catalogCache.get(record.essage);
    //      if (format == null) {
            try {
                format = catalog.getString(record.getMessage());
            } catch (java.util.MissingResourceException ex) {
                // Drop through.  Use record message as format
                format = record.getMessage();
            }
    //      catalogCache.put(record.message, format);
    //      }
    }
    // Do the formatting.
    try {
        Object parameters[] = record.getParameters();
        if (parameters == null || parameters.length == 0) {
        // No parameters.  Just return format string.
        return format;
        }
    // Is is a java.text style format?
        // Ideally we could match with
        // Pattern.compile("\\{\\d").matcher(format).find())
        // However the cost is 14% higher, so we cheaply check for
        // 1 of the first 4 parameters
        if (format.indexOf("{0") >= 0 || format.indexOf("{1") >=0 ||
                    format.indexOf("{2") >=0|| format.indexOf("{3") >=0) {
            return java.text.MessageFormat.format(format, parameters);
        }
        return format;
    } catch (Exception ex) {
        // Formatting failed: use localized format string.
        return format;
    }
}
我想知道为什么默认实现不是线程安全的

当缓存代码被注释掉时,同步应该被删除。这一问题是根据


它在OpenJDK中肯定是同步的,但在JavaDocs中可能不是

发件人:

从签名中删除“已同步”和“本机”。Javadoc生成一个API规范。这两个关键字不属于规范的签名,因为它们是特定于实现的。不需要记录关键字“native”。关键字“synchronized”表示应该在方法描述中描述的线程安全行为。线程安全方法本身可能不使用“synchronized”关键字,但可能会调用已同步的私有方法

p.S.

  • record.essage
    是源代码的实际输入错误
  • 注意如何多次调用
    record.getMessage()
    ,即使它在第一次调用时存储在本地
  • 代码允许将空引用传递到
    catalog.getString
    ,这将导致NPE失败

  • 我不认为它是同步的,无论是7还是8。它在OpenJDK中肯定是同步的,但在JavaDocs中可能不是(这很奇怪),例如:也许是为了避免加载大量资源包而占用内存?规范中没有这方面的直接细节。@uri不再显示在JavaDocs中。@jmehrens它在代码中,因此它由我们的内部静态分析工具标记。