【问题标题】:Jackson ObjectMapper & JsonGenerator - is it thread-safe?Jackson ObjectMapper & JsonGenerator - 它是线程安全的吗?
【发布时间】:2014-01-06 18:08:34
【问题描述】:

我目前有一个项目,它使用 jackson faster xml 使用自定义序列化器和反序列化器将 POJO 序列化/反序列化为 Json。据我了解,ObjectMapper 在创建和配置后是线程安全的。但是,我注意到在使用 JMeter 运行测试时偶尔会发生以下情况 -

  • 线程 1 进入 CustomerSerializer 开始序列化
  • 线程2进入CustomSerializer,中断线程1,从头到尾开始序列化
  • 线程 1 恢复,最后被序列化的东西不见了

似乎当第二个线程进入时 JsonGenerator 实例正在被重置——这肯定不应该发生吗?我检查了几个站点和线程,看看是否有我需要设置的设置或功能,但据我了解 ObjectMapper 重用 JsonGenerator 实例,这可能是问题吗?

以下是来自我的自定义序列化程序的 sn-p...

@Override
public final void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

    jsonGenerator.writeStartObject();

    ... Code here ....

    jsonGenerator.writeEndObject();

    closeJsonGenerator(jsonGenerator);
}

以及它的使用示例

SimpleModule sm = new SimpleModule();
sm.addSerializer(new myCustomSerializer());
new ObjectMapper().registerModule(sm)
                  .writeValue(new myObject());

【问题讨论】:

  • 请告诉我们你是如何使用ObjectMapperJsonGenerator的。
  • 添加了 sn-p 的代码

标签: java json fasterxml


【解决方案1】:

Jackson 的ObjectMapper 在每个序列化请求上创建一个新的JsonGenerator。从这个意义上说,它保证是线程安全的。我能看到的唯一可能导致您看到的行为的是,如果您的 CustomSerializer 有一些它正在共享的实例字段并且正在执行某种内部同步。

【讨论】:

  • 我需要看一下代码(它用于工作项目),据我所知,JsonGenerator 没有共享的地方。但是,从我通过代码调试可以看出,每次都返回同一个CustomSerializer实例?
  • @SCassidy1986 这很正常。您正在显式创建实例并在注册模块时传递它。 (除非您没有在任何地方使用相同的 ObjectMapper。)
  • 我使用的是相同的 ObjectMapper - 所以我猜测每次调用 CustomSerializer 时它不是创建一个新的 JsonGenerator,而是每次都传递同一个?或者我是否在脑海中混淆了 JsonGenerators 是如何创建/重用的?
  • @SCassidy1986 我认为您让他们感到困惑。任何对ObjectMapper#writeValue(..) 的调用都会在内部创建一个新的JsonGenerator 并使用它。这使它成为线程安全的。另一方面,您似乎正在使用单个CustomSerializer,因此它可能在线程之间共享。
  • 是的,因为我们使用相同的 ObjectMapper 实例,它正在重用序列化程序的单个实例,这似乎是问题所在。有没有办法告诉 ObjectMapper 每次都创建一个序列化器,而不是缓存它并重用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-19
  • 2011-11-09
  • 1970-01-01
  • 2014-10-30
相关资源
最近更新 更多