Не удалось найти подходящее решение в сети, поэтому я подумал, что правильный способ использования формата java.Нитевидный динамический шаблон для NumberFormat/DecimalFormat
1) В документации NumberFormat.java он говорит, что
Количество форматов, как правило, не синхронизированы. Рекомендуется создавать отдельные экземпляры формата для каждого потока.
Мы использовали объекты формата (статически инициализированные) в многопоточной среде без каких-либо проблем. Возможно, потому, что, как только форматы определены, мы не изменим их состояние (т. Е. После этого не создаются сеттеры)
2) Теперь мне нужно определить новый формат, который должен выводить одну или две значащие цифры после запятой , в зависимости от некоторой дополнительной логики. То, как я это делал, это определить новую оболочку формата и делегировать два различных DecimalFormat в зависимости от случая в перезаписанном методе #format (double, StringBuffer, FieldPosition). Вот код для этого:
private final NumberFormat FORMAT = new DecimalFormat() {
private final NumberFormat DECIMAL_FORMAT = new DecimalFormat("0.##");
private final NumberFormat DECIMAL_FORMAT_DIGIT = new DecimalFormat(
"0.0#");
public StringBuffer format(double number, StringBuffer result, java.text.FieldPosition fieldPosition) {
if ((number >= 10 && Math.ceil(number) == number)) {
return DECIMAL_FORMAT.format(number, result, fieldPosition);
} else {
return DECIMAL_FORMAT_DIGIT.format(number, result, fieldPosition);
}
}
};
Это лучшая практика? У меня есть опасения по поводу того, что на самом деле не используется класс-оболочка (он служит только для соответствия интерфейсу NumberFormat и делегирует всю работу во внутренние форматы). Я не хочу вызывать DecimalFormat # applyPattern(), поскольку я думаю, что это скомпрометирует волатильный параллелизм.
Благодаря
Неправильно использовать/совместно использовать экземпляры NumberFormat для нескольких потоков. Даже если вы не столкнулись с какой-либо проблемой, uptil сейчас, они произойдут, как только ваше приложение достигнет истинной параллельной обработки. У нас был аналогичный вариант использования DateFormat, в котором использовались статически созданные форматы дат, но мы масштабировали наше приложение для огромной обработки данных, когда n-параллельные процессы выкапывают данные, мы обнаружили, что формат может дать вам очень странный и неожиданный результат. Они могут не терпеть неудачу, но дадут некоторое неожиданное значение –
@SangramJadhav, так что вы, вероятно, сохраните многоразовый пул потоков в форматах, верно? – d56
Если вы хотите использовать общий формат, вам необходимо предоставить собственную синхронизацию. Или вы можете использовать ThreadLocal для объявления экземпляра формата, таким образом, каждый поток будет иметь свою собственную копию форматирования, и вам не нужно предоставлять синхронизацию. –