Che*_*eng 334 java json jackson
杰克逊图书馆的ObjectMapper课程似乎是线程安全的.
这是否意味着我应该将我声明ObjectMapper为像这样的静态字段
class Me {
private static final ObjectMapper mapper = new ObjectMapper();
}
Run Code Online (Sandbox Code Playgroud)
而不是像这样的实例级字段?
class Me {
private final ObjectMapper mapper = new ObjectMapper();
}
Run Code Online (Sandbox Code Playgroud)
Sta*_*Man 477
是的,这是安全的并且值得推荐.
您引用的页面中唯一的警告是,一旦共享,您就无法修改映射器的配置; 但你没有改变配置,所以没关系.如果你确实需要更改配置,你可以从静态块中执行此操作,它也可以.
编辑:(2013/10)
使用2.0及更高版本,可以通过注意到更好的方法来增强上述:使用ObjectWriter和ObjectReader可以构造的对象ObjectMapper.它们是完全不可变的,线程安全的,这意味着理论上甚至不可能导致线程安全问题(ObjectMapper如果代码尝试重新配置实例,可能会发生这种情况).
小智 43
虽然ObjectMapper是线程安全的,但我强烈建议不要将它声明为静态变量,尤其是在多线程应用程序中.甚至不是因为这是一种不好的做法,而是因为你正面临着陷入僵局的沉重风险.我是根据自己的经验告诉你的.我创建了一个具有4个相同线程的应用程序,这些线程从Web服务获取和处理JSON数据.根据线程转储,我的应用程序经常停止在以下命令上:
Map aPage = mapper.readValue(reader, Map.class);
Run Code Online (Sandbox Code Playgroud)
除此之外,表现并不好.当我用基于实例的变量替换静态变量时,停顿消失了,性能翻了两番.即,在40分钟.56秒内处理了2.4百万个JSON文档,而不是之前的2.5小时.
小智 6
如果您不想将其定义为静态最终变量但想要节省一些开销并保证线程安全,我从这个PR中学到了一个技巧。
private static final ThreadLocal<ObjectMapper> om = new ThreadLocal<ObjectMapper>() {
@Override
protected ObjectMapper initialValue() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return objectMapper;
}
};
public static ObjectMapper getObjectMapper() {
return om.get();
}
Run Code Online (Sandbox Code Playgroud)
归功于作者。
| 归档时间: |
|
| 查看次数: |
121557 次 |
| 最近记录: |