DecimalFormat.format(double) в разных потоках
Мне приходится печатать много форматированных десятичных значений во многих потоках параллельно. Для форматирования десятичных значений я использую java.text.DecimalFormat
, настроенный шаблоном.
Я знаю предупреждение из java doc DecimalFormat
:
Десятичные форматы, как правило, не синхронизированы. Рекомендуется создавать отдельные экземпляры формата для каждый поток. Если несколько потоков доступ к формату одновременно, он должен синхронизироваться снаружи.
Но я не знаю, относится ли это предупреждение к моему сценарию:
Я настраиваю java.text.DecimalFormat
один раз, когда приложение запускается (и сохраняет Formatter
в конечном поле). После этого я ТОЛЬКО использую метод format(double)
.
Причина, по которой я хочу это сделать, это: я не хочу терять производительность, создавая новый экземпляр DecimalFormat
каждый раз, когда мне нужно печатать отформатированный номер.
Я просмотрел код DecimalFormat.format(double)
, и он выглядит потокобезопасным, но я не уверен.
Не могли бы вы подтвердить, что использование DecimalFormat.format(double)
в конечном итоге является потокобезопасным, если не изменять конфигурацию форматирования, или объяснить, почему это не так?
Ответы
Ответ 1
Хотя текущая реализация может быть в конечном счете потокобезопасной, нет такой гарантии для будущих реализаций или для других JRE.
Вы проверили, что избежать new DecimalFormat()
является измеримым коэффициентом усиления производительности в вашем приложении?
Ответ 2
Просто используйте этот потокобезопасный фрагмент для NumberFormat
:
static ThreadLocal<NumberFormat> numberFormat = new ThreadLocal<NumberFormat>() {
@Override
public NumberFormat initialValue() {
return new DecimalFormat("00000");
}
};
Или в Java 8, как сказал Йеспер в комментарии:
private static ThreadLocal<NumberFormat> numberFormatter =
ThreadLocal.withInitial(() -> new DecimalFormat("00000"));
Ответ 3
Текущая реализация Hotspot для DecimalFormat делает вызов DecimalFormat.format(double) потокобезопасным, если вы не вызываете другие методы в этом экземпляре. Однако настоятельно рекомендуется не полагаться на это (возможно) временное поведение.
Считаете ли вы использование переменной ThreadLocal
, чтобы избежать слишком много new DecimalFormat()
?