我在哪里不是Threadsafe?

Jon*_*han 2 java multithreading thread-safety

我正在使用一个对象,它大致用作字符串映射的包装器:

public class Wrapper {
  private Map<String, String> values;
  private Formatter formatter;

  public BigDecimal getSpecialValue() {
    String result = values.get("Special");
    return formatter.formatNumber(result);
  }
}
Run Code Online (Sandbox Code Playgroud)

上述格式化器大致用作SimpleDateFormat的映射器

 public class Formatter {
   private static final NumberFormat NUMBER_FORMAT;

   public BigDecimal formatNumber(String s) {
     Number num = NUMBER_FORMAT.parse(s);
     if (num instanceof Integer) {
       return new BigDecimal((Integer) num);
     } else if (num instanceof Double) {
       return new BigDecimal((Double) num);
     } ...
   }
 }
Run Code Online (Sandbox Code Playgroud)

当我getSpecialValue()一次通过多个线程访问该方法时,一些行为准确,这只能通过并发访问来解释,例如可能有一个NumberFormatExceptionParseException哪个解析的字符串是.430.430而不是.430等等.

有两个方面引起我的兴趣:1.)包装器只能以只读方式访问.虽然对该集合的访问不同步,但我认为这应该始终有效.2.)在第一次尝试找到问题时,我改变了Wrapper类的构造函数来执行该formatNumber方法(显然是单线程),这消除了执行过程中的所有异常.

谁能解释一下?

编辑:Wrapper类中的映射填充在构造函数中,最明确的是单线程.然后设计包装器使得映射是不可变的.

Voo*_*Voo 9

只需在jdoc中搜索"thread",就会发现NumberFormat类的以下内容: Number formats are generally not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

  • 根据上述注释,使用ThreadLocal <NumberFormat> (2认同)