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

26 浏览
0 Comments

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

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

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

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

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

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

admin 更改状态以发布 2023年5月21日
0
0 Comments

尽管ObjectMapper是线程安全的,但我强烈不建议在多线程应用程序中将其声明为静态变量。
这不仅是因为这是一个不好的做法,而是因为你有很大的死锁风险。我是从我的经验中告诉你的。我创建了一个应用程序,有4个相同的线程从Web服务获取和处理JSON数据。
根据线程转储,我的应用程序经常在下面的命令上停顿:

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

此外,性能也不好。
当我用基于实例的变量替换静态变量时,停顿消失了,而性能增加了四倍。也就是说,处理了240万个JSON文档,用时40分钟56秒,而之前需要2.5小时。

0
0 Comments

是的,这是安全和推荐的。

你引用的页面唯一的注意事项是一旦共享了映射器,就无法修改其配置;但是你没有改变配置,所以没问题。如果你确实需要更改配置,你可以在静态块中完成,这也没问题。

编辑: (2013/10)

使用2.0及以上版本,可以通过使用ObjectWriterObjectReader对象来改进上述过程,它们可以由ObjectMapper构造。
它们是完全不可变的,线程安全,这意味着甚至理论上也不可能出现线程安全问题(如果代码尝试重新配置实例,则可能会出现ObjectMapper的线程安全问题)。

0