2010-12-08 10 views
21

Tengo que imprimir muchos valores decimales formateados en muchos subprocesos en paralelo. Para formatear los valores decimales utilizo un java.text.DecimalFormat configurado por un patrón. Soy consciente de la advertencia del doc java de DecimalFormat:DecimalFormat.format (doble) en diferentes subprocesos

formatos decimales son generalmente no sincronizados. Se recomienda crear instancias de formato separadas para cada hilo. Si múltiples hilos acceden a un formato al mismo tiempo, debe sincronizarse externamente.

Pero no sé si esta advertencia se aplica a mi escenario: configuro el java.text.DecimalFormat una vez cuando se inicia la aplicación (y almacenan la Formatter en un campo final). Después de eso SÓLO uso el método format(double).

La razón por la que quiero hacer esto es: no quiero perder rendimiento creando una nueva instancia de DecimalFormat cada vez que necesito imprimir un número formateado.

Miré el código DecimalFormat.format(double) y parece ser seguro para subprocesos, pero no estoy seguro.

¿Podría confirmar que el uso de DecimalFormat.format(double) es finalmente seguro para hilos, cuando no cambia la configuración del formateador, o explica por qué no lo es?

+2

A "workarround" es utilizar ThreadLocal, pero es es no es la pregunta. – Ralph

+0

Otra solución es sincronizar en el objeto DecimalFormat en las conversiones. O bien (a) hace pocas conversiones y la sincronización no afectará mucho al rendimiento, o (b) realiza muchas conversiones, en cuyo caso los objetos DecimalFormat pueden reutilizarse para conversiones en el mismo subproceso, por lo tanto, sus costos de construcción deberían ser insignificantes. –

Respuesta

18

Si bien la implementación actual puede ser eventualmente segura para subprocesos, no existe tal garantía para las próximas implementaciones, o para otros JRE.

¿Ha verificado que evitar new DecimalFormat() es una ganancia de rendimiento mensurable en su aplicación?

+0

En una prueba, descubrí que se necesitan aproximadamente ~ 23 ms para instanciar la instancia de NumberFormat y Decimal format, que creo que es un tiempo de ejecución desaprovechado, ¿se aconseja alguna solución? –

6

La implementación de Hotspot actual para DecimalFormat realiza la llamada a DecimalFormat.format (doble) thread-safe si no llama a otros métodos en esta instancia. Sin embargo, se recomienda encarecidamente no confiar en este (tal vez) comportamiento temporal.

¿Ha considerado utilizar una variable ThreadLocal para evitar demasiados new DecimalFormat()?

13

sólo tiene que utilizar este fragmento flujos seguros para NumberFormat:

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

O en Java 8, como se dijo Jesper en el comentario:

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

que se puede convertir a una expresión lambda en Java 8: 'private static ThreadLocal numberFormatter = ThreadLocal.withInitial (() -> new DecimalFormat (" 0.00 "));' –

Cuestiones relacionadas