web-dev-qa-db-ja.com

異なるスレッドのDecimalFormat.format(double)

多くのスレッドで多くのフォーマットされた10進値を並行して出力する必要があります。 10進値をフォーマットするには、パターンで構成された_Java.text.DecimalFormat_を使用します。 Java doc of DecimalFormat:からの警告を認識しています。

10進形式は、通常、同期されません。スレッドごとに個別のフォーマットインスタンスを作成することをお勧めします。複数のスレッドが同時にフォーマットにアクセスする場合は、外部で同期する必要があります。

しかし、この警告が私のシナリオに当てはまるかどうかはわかりません。アプリケーションの起動時に_Java.text.DecimalFormat_を1回構成します(最後のフィールドにFormatterを格納します)。その後は、format(double)メソッドのみを使用します。

これを実行する理由は、フォーマットされた数値を出力する必要があるたびに新しいDecimalFormatインスタンスを作成してパフォーマンスを低下させたくないからです。

DecimalFormat.format(double)コードを調べたところ、スレッドセーフのように見えましたが、よくわかりません。

フォーマッターの構成を変更しない場合、DecimalFormat.format(double)の使用が最終的にスレッドセーフであることを確認できますか、または変更されない理由を説明してください

29
Ralph

現在の実装は最終的にスレッドセーフになる可能性がありますが、今後の実装や他のJREに対するそのような保証はありません。

new DecimalFormat()を回避することが、アプリケーションで測定可能なパフォーマンスの向上であることを確認しましたか?

22
mfx

NumberFormatには、このスレッドセーフなスニペットを使用してください。

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

または、Jesperがコメントで述べたように、Java 8)で:

private static ThreadLocal<NumberFormat> numberFormatter = 
                  ThreadLocal.withInitial(() -> new DecimalFormat("00000"));
26
Dariusz

DecimalFormatの現在のホットスポット実装は、このインスタンスで他のメソッドを呼び出さない場合、DecimalFormat.format(double)をスレッドセーフで呼び出します。ただし、この(おそらく)一時的な動作に依存しないことを強くお勧めします。

new DecimalFormat()が多すぎないように、ThreadLocal変数を使用することを検討しましたか?

6
Guillaume