DecimalFormat.format(double)在不同的线程中

Ral*_*lph 29 java multithreading thread-safety

我必须在许多线程中并行打印许多格式化的十进制值.要格式化十进制值,我使用java.text.DecimalFormat由模式配置.我知道来自java doc的警告DecimalFormat:

十进制格式通常不同步.建议为每个线程创建单独的格式实例.如果多个线程同时访问格式,则必须在外部进行同步.

但我不知道这个警告是否适用于我的场景:我java.text.DecimalFormat在应用程序启动时配置一次(并将其存储Formatter在最终字段中).之后我只使用这个format(double)方法.

我想这样做的原因是:DecimalFormat每次我需要打印格式化的数字时,我不想通过创建新实例来失去性能.

我查看了DecimalFormat.format(double)代码,它看起来是线程安全的,但我不确定.

DecimalFormat.format(double)在没有改变格式化程序的配置时,你能否确认最终的线程是否安全,或解释为什么不是?

Dar*_*usz 27

只需使用此线程安全的代码段NumberFormat:

static ThreadLocal<NumberFormat> numberFormat = new ThreadLocal<NumberFormat>() {
    @Override
    public NumberFormat initialValue() {
        return new DecimalFormat("00000");
    }
};
Run Code Online (Sandbox Code Playgroud)

或者在Java 8中,正如Jesper在评论中所说:

private static ThreadLocal<NumberFormat> numberFormatter = 
                  ThreadLocal.withInitial(() -> new DecimalFormat("00000"));
Run Code Online (Sandbox Code Playgroud)

  • 可以在Java 8中转换为lambda表达式:`private static ThreadLocal <NumberFormat> numberFormatter = ThreadLocal.withInitial(() - > new DecimalFormat("0.00"));` (6认同)
  • 消极的。ThreadLocal 实例有很多令人不快的副作用(例如 JEE 环境中的内存泄漏)。将它用于如此微不足道的优化是一个非常糟糕的主意。 (3认同)

mfx*_*mfx 23

虽然当前的实现可能最终是线程安全的,但是对于即将到来的实现或其他JRE没有这样的保证.

您是否已验证避免new DecimalFormat()在您的应用程序中获得可衡量的性能提升?

  • DecimalFormat不是线程安全的。请参阅:https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html“通常不同步十进制格式。建议为每个线程创建单独的格式实例。如果有多个线程同时访问一种格式,则必须在外部进行同步。” (2认同)

Gui*_*ume 6

如果不在此实例上调用其他方法,则DecimalFormat的当前Hotspot实现将调用DecimalFormat.format(double)线程安全.但是强烈建议不要依赖这种(可能)临时行为.

您是否考虑过使用ThreadLocal变量来避免太多new DecimalFormat()