2013-09-03 1 views
7

У меня есть требование, чтобы преобразовать входящие даты в формате строка "20130212" (ГГГГММДД) до 12/02/2013 (DD/MM/YYYY)Дата преобразования с ThreadLocal

с использованием ThreadLocal. Я знаю способ сделать это без ThreadLocal. Может кто-нибудь мне помочь?

Конверсия без 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

Зачем вам нужно использовать ThreadLocal? – JohnMark13

+0

Поскольку SimpleDateFormats (и даже большинство других экземпляров Format) не являются потокобезопасными. См. Мой [сообщение в блоге] (https://stijndewitt.wordpress.com/2014/07/28/how-javas-text-formats-can-subtly-break-your-code/) по этой теме. –

ответ

9

ThreadLocal в Java является способом достижения потокобезопасности помимо написания неизменных классов. Поскольку SimpleDateFormat не является потокобезопасным, вы можете использовать ThreadLocal, чтобы сделать его потокобезопасным.

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

Спасибо, Ричи, но ваш класс не работает, говоря, что класс тела, декларация поля не завершена. Добавлены дополнительные закрывающие фигурные скобки, но до сих пор нет удачи. Кроме того, как удалить эти threadlocal-ссылки после завершения calll. – user2680017

+0

проверить сейчас. Я добавил фигурные скобки. – Richie

+0

Почему вы хотите удалить ссылки ThreadLocal? – Richie

9

Идея заключается в том, что SimpleDateFormat не поточно-так в мутил нарезкой приложение, которое вы не можете разделить экземпляр SimpleDateFormat между несколькими потоками. Но поскольку создание SimpleDateFormat является дорогостоящей операцией, мы можем использовать в качестве временного решения ThreadLocal

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

Неужели люди это делают? Если вы (оригинальный l-плакат) не понимаете ThreadLocals правильно, я бы порекомендовал их не использовать. Возможно, я бы рассмотрел FastDateFormat из Commons Lang или DateTimeFormat из библиотеки JodaTime. Вот длинная и интересная тема по этому вопросу. Http://jsr166-concurrency.10961.n7.nabble.com/Threadlocals-and-memory-leaks-in-J2EE-td3960.html – JohnMark13

+0

+1 .. или синхронизированный SimpleDateFormat –

+1

@ JohnMark13: Да, люди это делают. Я также [рекомендую] (https://stijndewitt.wordpress.com/2014/07/28/how-javas-text-formats-can-subtly-break-your-code/). Как он правильно понимает ThreadLocals? Джошуа Блох, автор Effective Java, говорит по вашей ссылке: «Этот поток усеян дезинформацией. [..] В локаторах потоков нет ничего неправильного: они не вызывают утечки памяти, они не медленны». Обсуждение касается ошибок в Tomcat и некоторых других приложениях, которые используют пулы потоков и имеют проблемы с реализацией ThreadLocals. Они могут и должны быть исправлены в этих приложениях. –