【问题标题】:Jackson's JsonSerializer and thread safetyJackson 的 JsonSerializer 和线程安全
【发布时间】:2014-10-30 02:28:41
【问题描述】:

我的 Spring 项目中有一个简单的JsonSerializer

public class JsonDateTimeSerializer extends JsonSerializer<Date> {
    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider sp) throws IOException {
        gen.writeString(DATE_FORMAT.format(value));
    }
}

并像这样使用它:

@JsonSerialize(using = JsonDateTimeSerializer.class)
public Date getDate() {
    return date;
}

我是否必须注意线程安全并使DATE_FORMAT 同步(因为SimpleDateFormat 不是线程安全的)?我不确定@JsonSerialize 究竟是如何工作的——它是否只在所有线程中创建单个序列化实例?还是为每个转换创建单独的实例?

【问题讨论】:

    标签: java json spring multithreading jackson-databind


    【解决方案1】:

    如果JsonDateTimeSerializer.serialize 可能被多个线程调用,那么SimpleDateFormat 的这种使用是不安全的。在other answer 中很好地解释了避免SimpleDateFormat 上的低效同步的常用方法。适应您的用例:

    public class JsonDateTimeSerializer extends JsonSerializer<Date> {
    
        private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() {
            @Override
            protected SimpleDateFormat initialValue() {
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            }
        };
    
        @Override
        public void serialize(Date value, JsonGenerator gen, SerializerProvider sp) throws IOException {
            gen.writeString(formatter.get().format(value));
        }
    }
    

    【讨论】:

    • 我也遇到过同样的多线程问题,当我添加上面的代码时,它就消失了。所以我认为正确的答案是这个问题。
    【解决方案2】:

    当 Jackson 第一次看到您的类型时,(取决于类型)它将为每个属性构建一个带有适当 JsonSerializers 的 BeanSerializer。此BeanSerializer 被缓存并重用于相同Type 的未来序列化。

    因此,JsonDateTimeSerializer(每个类型)的单个实例(已在 JsonDateTimeSerializer 中注册)将被重用于所有序列化。因此,如果您计划跨多个线程使用ObjectMapper,它必须是线程安全的。 (你应该因为 ObjectMapper 本身是线程安全的。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 2011-11-04
      • 1970-01-01
      • 2011-06-09
      • 2014-03-04
      • 1970-01-01
      相关资源
      最近更新 更多