2013-09-03 10 views
7

Mam wymaganie, aby przekonwertować datę przychodzące format string "20130212" (RRRRMMDD) do 12/02/2013 (dd/mm/rrrr)Data konwersji z ThreadLocal

wykorzystaniem ThreadLocal. Znam sposób to zrobić bez ThreadLocal. Czy ktoś może mi pomóc?

konwersji bez 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

Dlaczego musisz używać ThreadLocal? – JohnMark13

+0

Ponieważ SimpleDateFormats (a także większość innych instancji formatu) nie są bezpieczne dla wątków. Zobacz mój [post na blogu] (https://stijndewitt.wordpress.com/2014/07/28/how-javas-text-formats-can-subtly-break-your-code/) na ten temat. –

Odpowiedz

9

ThreadLocal w Javie jest sposobem osiągnięcia wątku bezpieczeństwa oprócz pisania klas niezmienne. Ponieważ SimpleDateFormat nie jest bezpieczny dla wątków, możesz użyć wątku ThreadLocal, aby zapewnić bezpieczny wątek.

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

Dzięki Richie, ale twoja klasa nie działa mówiąc, że ciało klasy, deklaracja pola nie została zakończona.i dodano dodatkowe nawiasy klamrowe, ale wciąż nie ma szczęścia.i także, jak usunąć te referencje wątkowych po zakończeniu calll. – user2680017

+0

Sprawdź teraz. Dodałem teraz aparaty ortodontyczne. – Richie

+0

Dlaczego chcesz usunąć odniesienia ThreadLocal? – Richie

9

Ideą jest to, że SimpleDateFormat nie jest bezpieczny wątku więc w app mutil gwintowane nie można dzielić wystąpienie SimpleDateFormat między wieloma wątkami. Ale ponieważ tworzenie SimpleDateFormat jest kosztowna operacja możemy użyć ThreadLocal jako obejście

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

Czy ludzie to robią? Jeśli (oryginalny plakat L) nie rozumie poprawnie ThreadLocals, nie polecałbym ich używać. Chciałbym rozważyć FastDateFormat z Commons Lang lub DateTimeFormat z biblioteki JodaTime. Oto długi i interesujący wątek na ten temat .. http://jsr166-concurrency.10961.n7.nabble.com/Threadlocals-and-memory-leaks-in-J2EE-td3960.html – JohnMark13

+0

+1 .. lub zsynchronizowane SimpleDateFormat –

+1

@ JohnMark13: Tak, ludzie to robią. Ja również [polecam] (https://stijndewitt.wordpress.com/2014/07/28/how-javas-text-formats-can-subtly-break-your-code/) it. Jak on nie rozumie poprawnie ThreadLocals? Joshua Bloch, autor Effective Java, mówi na twoim linku: "Ten wątek jest zaśmiecony dezinformacją. [..] Nie ma nic nie w porządku z lokalnymi wątkami: Nie powodują one przecieków pamięci, nie są powolne.". Dyskusja dotyczy błędów w Tomcat i kilku innych aplikacjach korzystających z pul wątków oraz problemów z implementacją ThreadLocals. Mogą i powinny zostać naprawione w tych aplikacjach. –