I have to print many formatted decimal values in many threads in parallel. To format the decimal values I use a java.text.DecimalFormat
configured by a pattern. I am aware of the warning from the java doc of DecimalFormat
:
Decimal formats are generally not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
But I don’t know if this warning applies to my scenario: I configure the java.text.DecimalFormat
once when the application starts (and store the Formatter
in a final field). After that I ONLY use the format(double)
method.
The reason why I want to do this is: I don’t want to lose performance by creating a new DecimalFormat
instance every time I need to print a formatted number.
I looked at the DecimalFormat.format(double)
code and it looks to be thread safe, but I am not sure.
Could you please confirm that the usage of DecimalFormat.format(double)
is eventually thread safe, when not changing the configuration of the formatter, or explain why it is not?
DecimalFormat isn't thread-safe, thus we should pay special attention when sharing the same instance between threads.
Just use %. 2f as the format specifier. This will make the Java printf format a double to two decimal places. /* Code example to print a double to two decimal places with Java printf */ System.
DecimalFormat format = new DecimalFormat("#. #####"); value = Double. valueOf(format. format(41251.50000000012343));
You can use the DecimalFormat class to format decimal numbers into locale-specific strings. This class allows you to control the display of leading and trailing zeros, prefixes and suffixes, grouping (thousands) separators, and the decimal separator.
Just use this thread-safe snippet for NumberFormat
:
static ThreadLocal<NumberFormat> numberFormat = new ThreadLocal<NumberFormat>() { @Override public NumberFormat initialValue() { return new DecimalFormat("00000"); } };
Or in Java 8, as Jesper said in comment:
private static ThreadLocal<NumberFormat> numberFormatter = ThreadLocal.withInitial(() -> new DecimalFormat("00000"));
While the current implementation may be eventually thread-safe, there is no such guarantee for coming implementations, or for other JREs.
Have you verified that avoiding new DecimalFormat()
is a measurable performance gain in your application?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With