2010-12-08 9 views
21

Ich muss viele formatierte Dezimalwerte in vielen Threads parallel drucken. Um die Dezimalwerte zu formatieren, verwende ich eine java.text.DecimalFormat konfiguriert durch ein Muster. Ich bin mir der Warnung des Java-doc von DecimalFormat:DecimalFormat.format (double) in verschiedenen Threads

Dezimalformate sind in der Regel nicht synchronisiert. Es wird empfohlen, separate Format-Instanzen für jeden Thread zu erstellen. Wenn mehrere Threads gleichzeitig auf ein Format zugreifen, muss extern synchronisiert werden.

Aber ich weiß nicht, ob diese Warnung zu meinem Szenario gilt: ich die java.text.DecimalFormat einmal konfigurieren, wenn die Anwendung gestartet wird (und speichern Sie die Formatter in einem letzten Feld). Danach benutze ich NUR die format(double) Methode.

Der Grund, warum ich dies tun möchte, ist: Ich möchte nicht die Leistung verlieren, indem ich jedes Mal eine neue DecimalFormat Instanz erstelle, wenn ich eine formatierte Zahl drucken muss.

Ich schaute auf den Code DecimalFormat.format(double) und es scheint Thread sicher zu sein, aber ich bin mir nicht sicher.

Könnten Sie bitte bestätigen, dass die Verwendung von DecimalFormat.format(double) schließlich threadsicher ist, wenn Sie nicht die Konfiguration des Formatierungsprogramms ändern oder erklären, warum dies nicht der Fall ist?

+2

A "workarround" ist Thread zu verwenden, aber ist nicht die Frage. – Ralph

+0

Eine andere Problemumgehung besteht darin, das DecimalFormat-Objekt für Konvertierungen zu synchronisieren. Entweder (a) Sie wenige Konvertierungen und Synchronisierung hat keinen Einfluss auf die Leistung, oder (b) Sie viele Konvertierungen, in diesem Fall können DecimalFormat Objekte wahrscheinlich für Konvertierungen im selben Thread wiederverwendet werden, daher sollten ihre Baukosten vernachlässigbar sein. –

Antwort

18

Während die aktuelle Implementierung eventuell Thread-sicher ist, gibt es keine Garantie für kommende Implementierungen oder für andere JREs.

Haben Sie verifiziert, dass die Vermeidung von new DecimalFormat() einen messbaren Leistungsgewinn in Ihrer Anwendung darstellt?

+0

On One Test Ich zufällig herauszufinden, dass es etwa ~ 23 ms dauert, NumberFormat und Decimal-Format-Instanz instanziieren, die ich denke, ist eine verschwendete Ausführungszeit, jede mögliche Abhilfe empfohlen? –

6

Aktuelle Hotspot-Implementierung für DecimalFormat machen den Aufruf von DecimalFormat.format (double) Thread-sicher, wenn Sie keine anderen Methoden für diese Instanz aufrufen. Es wird jedoch dringend empfohlen, sich nicht auf dieses (vielleicht) temporäre Verhalten zu verlassen.

Haben Sie darüber nachgedacht, eine ThreadLocal Variable zu verwenden, um zu viele new DecimalFormat() zu vermeiden?

13

Verwenden Sie einfach diesen thread-safe-Snippet für NumberFormat:

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

Oder in Java 8, wie Jesper in Kommentar sagte:

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

Was in Java 8 in einen Lambda-Ausdruck umgewandelt werden kann: 'private static ThreadLocal numberFormatter = ThreadLocal.withInitial (() -> neues DecimalFormat (" 0.00 "));' –

Verwandte Themen