【发布时间】:2016-05-30 09:07:24
【问题描述】:
一直没能在网络上找到合适的解决方案,所以想问问我使用java格式的方式是否正确。
1) 在 NumberFormat.java 文档中它说
数字格式通常不同步。建议为每个线程创建单独的格式实例。
到目前为止,我们一直在多线程环境中使用格式对象(静态初始化),没有出现任何问题。是不是因为一旦定义了格式,我们的状态就没有改变(即之后没有调用setter)
2) 我现在需要定义一个新格式,它应该在逗号后输出一个或两个有效数字,具体取决于一些额外的逻辑。我这样做的方式是定义一个新的格式包装器并根据覆盖的#format(double, StringBuffer, FieldPosition) 方法中的情况委托给两个不同的DecimalFormat。这是代码:
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() ,因为我认为这会损害 volatile 并发。
谢谢
【问题讨论】:
-
在多个线程中使用/共享 NumberFormat 实例不是一个好习惯。即使您没有遇到任何问题,但到目前为止,一旦您的应用程序达到真正的并发处理,它们就会发生。我们对 DateFormat 有类似的用例,其中使用了静态创建的日期格式,但是我们将应用程序扩展为大型数据处理,其中 n 个并发进程正在大量生成数据,我们发现该格式会给您带来非常奇怪和意想不到的结果。他们可能不会失败,但会给出一些意想不到的价值
-
@SangramJadhav,所以您可能会保留一个可重用的格式线程池,对吧?
-
如果要分享格式,需要我们自己提供同步。或者您可以使用 ThreadLocal 来声明格式实例,这样每个线程都将拥有自己的格式化程序副本,而您不必提供同步。
-
是的,如果,那么我将使用 ThreadLocal。谢谢。您对第 2 点有什么建议吗?
标签: java multithreading formatting format decimalformat