NumberFormat.format()返回不一致的值

时间:2016-02-02 14:45:59

标签: java multithreading

我正在并行解析多个文件,有时候,format()方法不会返回正确的值。

Number parse = numberFormat.parse(val);
String format = numberFormat.format(parse);
format.equals(parse); //returns false sometimes
  • 起初我认为这是因为格式化方法不是线程安全的,但每个线程使用numberformat.clone()

我还尝试为每个线程创建new NumberFormat(),并为ThreadLocal<NumberFormat>创建一个初始值,然后调用get()方法,所有这些都有同样的问题。

  • 在调试器中,对表达式的求值始终在断点处返回正确的值。

  • 我尝试多行String format = numberFormat.format(parse);,结果是随机地,一行或几行返回一个完全错误的值,另一行返回正确的行。

我99%确定它是一个线程问题,并且对某些内容进行了并发访问,可能是numberFormat本身。

我可能没有使用正确的方法使其线程安全,但在我的理解中,使用clone()new应该摆脱这种担忧。

有关导致问题的原因,以及如何解决问题的任何线索?

编辑:

以下是使用IntelliJ IDEA制作的两个屏幕截图,以展示问题:

1st test case, two format are wrong

2nd test case, 3 format are wrong

2 个答案:

答案 0 :(得分:0)

从来没有任何保证NumberFormat的format方法将返回与您解析数字完全相同的String。事实上,许多字符串可以产生相同的数字值。

首先,考虑尾随零:

NumberFormat numberFormat = NumberFormat.getInstance();
Number parsed = numberFormat.parse("1.500000000000");
String formatted = numberFormat.format(parsed);
System.out.println(formatted);      // prints 1.5

其次,NumberFormat不解析完整的String,如Double.valueOf,Integer.valueOf等。它尽可能地从String中解析,并忽略尾随字符。以下是将成功解析的所有有效操作,而不会抛出ParseException:

NumberFormat numberFormat = NumberFormat.getInstance();
numberFormat.parse("1.500000000000");
numberFormat.parse("1.5           ");
numberFormat.parse("1.5-----------");
numberFormat.parse("1.5helloworld");

以上所有调用都返回1.5。

答案 1 :(得分:0)

扩展NumberFormat类并同步format方法:

class SynchronizedNumberFormat extends NumberFormat {

    public synchronized String format(Number number) {
        return super.format(number);
    }

    //unimplemented methods...

}