2013-09-03 5 views
7

Ich habe eine Verpflichtung eingehendes Datum String-Format "20130212" (JJJJMMTT) zu konvertieren 2013.12.02 (TT/MM/JJJJ)Datum Konvertierung mit Thread

mit ThreadLocal. Ich kenne einen Weg, dies ohne die ThreadLocal zu tun. Kann mir jemand helfen?

Umwandlung ohne ThreadLocal:

final SimpleDateFormat format2 = new SimpleDateFormat("MM/dd/yyyy"); 
    final SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMdd"); 
    final Date date = format1.parse(tradeDate); 
    final Date formattedDate = format2.parse(format2.format(date)); 
+0

Warum brauchen Sie ein ThreadLocal? – JohnMark13

+0

Da SimpleDateFormats (und tatsächlich die meisten anderen Format-Instanzen) nicht threadsicher sind. Siehe meinen [Blogpost] (https://stijndewitt.wordpress.com/2014/07/28/how-java-text-formats-can-subtly-break-your-code/) zu diesem Thema. –

Antwort

9

Thread in Java ein Weg ist, Thread-Sicherheit außer Schreiben unveränderliche Klassen zu erreichen. Da SimpleDateFormat nicht Thread-sicher ist, können Sie ThreadLocal verwenden, um es threadsicher zu machen.

class DateFormatter{ 

    private static ThreadLocal<SimpleDateFormat> outDateFormatHolder = new ThreadLocal<SimpleDateFormat>() { 
    @Override 
    protected SimpleDateFormat initialValue() { 
     return new SimpleDateFormat("MM/dd/yyyy"); 
    } 
}; 

private static ThreadLocal<SimpleDateFormat> inDateFormatHolder = new ThreadLocal<SimpleDateFormat>() { 
    @Override 
    protected SimpleDateFormat initialValue() { 
     return new SimpleDateFormat("yyyyMMdd"); 
    } 
}; 

public static String formatDate(String date) throws ParseException { 
    return outDateFormatHolder.get().format(
      inDateFormatHolder.get().parse(date)); 
}   
} 
+0

Dank Richie, aber Ihre Klasse funktioniert nicht sagen Klassenkörper, Feld Erklärung nicht abgeschlossen.Ich fügte zusätzliche schließende Klammern aber noch kein Glück.und auch, wie diese threadlocal Referenzen entfernen, sobald calll vorbei ist. – user2680017

+0

Jetzt prüfen. Ich habe jetzt die Zahnspange hinzugefügt. – Richie

+0

Warum möchten Sie ThreadLocal Referenzen entfernen? – Richie

9

Die Idee dahinter ist, dass Simple ist nicht Thread-sicher-so in einem mutil-threaded app Sie nicht eine Instanz von Simple zwischen mehreren Threads gemeinsam nutzen können. Da aber die Schaffung von Simple eine teure Operation ist, können wir eine Thread als Abhilfe verwenden

static ThreadLocal<SimpleDateFormat> format1 = new ThreadLocal<SimpleDateFormat>() { 
    @Override 
    protected SimpleDateFormat initialValue() { 
     return new SimpleDateFormat("yyyy-MM-dd"); 
    } 
}; 

public String formatDate(Date date) { 
    return format1.get().format(date); 
} 
+1

Tun die Leute das? Wenn Sie (das ursprüngliche l Poster) ThreadLocals nicht richtig verstehen, würde ich empfehlen, sie nicht zu verwenden. Ich würde vielleicht FastDateFormat von Commons Lang oder DateTimeFormat von der JodaTime-Bibliothek betrachten. Hier ist ein langer und interessanter Thread zum Thema .. http://jsr166-concurrency.10961.n7.nabble.com/Threadlocals-and-memory-leaks-in-J2EE-td3960.html – JohnMark13

+0

+1 .. oder a synchronisiert SimpleDateFormat –

+1

@ JohnMark13: Ja, die Leute machen das. Ich empfehle es auch (https://stijndewitt.wordpress.com/2014/07/28/how-java-text-formats-can-subtly-break-your-code/) es. Wie versteht er ThreadLocals nicht richtig? Joshua Bloch, Autor von Effective Java, sagt auf deinem Link: "Dieser Thread ist übersät mit Fehlinformationen. [..] Es gibt nichts an sich mit Thread-Locals falsch: Sie verursachen keine Speicherlecks. Sie sind nicht langsam." In der Diskussion geht es um Fehler in Tomcat und einigen anderen Apps, die Thread-Pools verwenden und Probleme mit der Implementierung von ThreadLocals haben. Sie können und sollten in diesen Apps behoben werden. –