ThreadLocal для многопоточного доступа к SimpleDateFormat

У меня есть несколько шаблонов дат Java, и я хочу использовать их несколько раз в SimpleDateFormat объекты в разных потоках, через статические ссылки, для скорости.

Код будет выглядеть примерно так (внутри класса, скажем, FormatClass):

private static String[] PATTERNS = new String[] {...};

public ThreadLocal<SimpleDateFormat[]> LOCAL_FORMATS = new ThreadLocal<SimpleDateFormat[]>
{
    @Override
    protected SimpleDateFormat[] initialValue()
    {
        List<SimpleDateFormat> formatList = new ArrayList<SimpleDateFormat>();

        for (String pattern:PATTERNS)
        {
            formatList.add(new SimpleDateFormat(pattern);
        }

        return formatList.toArray(new SimpleDateFormat[0]);
    }
}

Используя приведенный выше код, метод другого класса может format (или же parse) несколько строк даты следующим образом:

public static void printFormatted(String date)
{
    for (SimpleDateFormat sdf:FormatClass.LOCAL_FORMATS.get())
    {
        System.out.println(sdf.format(date));
    }
}

где printFormatted() Метод может быть или не быть статическим, но определенно будет доступен нескольким различным потокам.

Будет ли вышеуказанный подход работать так, как ожидалось?

4 ответа

Решение

Чтобы ответить на ваш вопрос прямо: да, каждый поток будет иметь свою собственную уникальную копию, как рекомендовано в документе SimpleDateFormat.

Это выглядит довольно хорошо, но вы можете легко протестировать его с помощью многопоточной программы. Просто напечатайте идентификатор потока (Thread.currentThread().toString()) а также System.identifyHashCode(simpleDateFormat) и убедитесь, что вы получаете уникальные копии для каждого потока и, соответственно, повторно используете их.

Это работает хорошо, но код относительно сложен. Я бы предложил проверить, может быть, вы можете назначить SimpleDateFormat какой-то локальной переменной внутри метода (всегда локально для потока). Это хорошо работает, когда многие значения отформатированы в цикле, который затем может быть внутри одного и того же метода.

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

Другие вопросы по тегам