我应该将 Jackson 的 ObjectMapper 声明为静态字段吗?

2022-08-31 04:33:23

Jackson 库的类似乎是线程安全的ObjectMapper

这是否意味着我应该像这样声明my为静态字段ObjectMapper

class Me {
    private static final ObjectMapper mapper = new ObjectMapper();
}

而不是像这样作为实例级字段?

class Me {
    private final ObjectMapper mapper = new ObjectMapper();
}

答案 1

是的,这是安全的,建议使用。

您引用的页面中唯一需要注意的是,一旦共享映射器,就无法修改映射器的配置;但是您没有更改配置,因此没关系。如果您确实需要更改配置,则可以从静态块中执行此操作,这也很好。

编辑: (2013/10)

对于 2.0 及更高版本,可以通过指出有更好的方法来增强上述内容:use and objects,它可以由 .它们是完全不可变的,线程安全的,这意味着理论上甚至不可能导致线程安全问题(如果代码尝试重新配置实例,则可能发生此问题)。ObjectWriterObjectReaderObjectMapperObjectMapper


答案 2

尽管 ObjectMapper 是线程安全的,但我强烈建议不要将其声明为静态变量,尤其是在多线程应用程序中。甚至不是因为这是一种不好的做法,而是因为你有严重的死锁风险。我是从我自己的经验中讲述的。我创建了一个应用程序,其中包含4个相同的线程,这些线程从Web服务获取和处理JSON数据。根据线程转储,我的应用程序经常在以下命令上停止:

Map aPage = mapper.readValue(reader, Map.class);

除此之外,性能也不好。当我用基于实例的变量替换静态变量时,停滞消失了,性能翻了两番。也就是说,在40分钟56秒内处理了240万个JSON文档,而不是之前的2.5小时。