Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DecimalFormat.format(double) in different threads

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?

like image 625
Ralph Avatar asked Dec 08 '10 12:12

Ralph


People also ask

Is DecimalFormat thread safe?

DecimalFormat isn't thread-safe, thus we should pay special attention when sharing the same instance between threads.

How do you format a double value?

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.

How do you convert a decimal to a double?

DecimalFormat format = new DecimalFormat("#. #####"); value = Double. valueOf(format. format(41251.50000000012343));

What is the use of DecimalFormat in Java?

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.


2 Answers

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")); 
like image 127
Dariusz Avatar answered Sep 17 '22 19:09

Dariusz


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?

like image 32
mfx Avatar answered Sep 16 '22 19:09

mfx