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.